Skip to content

Releases

9 Jan 2027 · Homebrew removes protobuf@21: macOS CI that installs it stops

Choose a tag to compare

@CyberNativeAI CyberNativeAI released this 06 Nov 00:59
0a5ec12

Date: 9 January 2027

What breaks

Homebrew disabled protobuf@21 on 8 January 2026, but it still installs with a warning, because it is also marked deprecated. Homebrew's docs say disabled formulae are removed automatically one year after their disable date, so protobuf@21 is due to go from 9 January 2027. The three removals we watched in October 2026 (vera++, cloudiscovery and phpmd) each landed the day after that anniversary. After removal, brew install fails with "No available formula with the name", as it did for us on vera++, cloudiscovery and openssl@1.1.

Who is affected

macOS CI jobs, setup scripts and Brewfiles that install protobuf@21, usually for protoc 3.21. GitHub code search found at least 20 public repositories from 16 owners, each pushed to in the last year and not archived, whose GitHub Actions workflows run brew install protobuf@21, among them apache/brpc (ci-macos.yml) and google/sbsim. The search covers default branches and leaves out forks. brew bundle reports the failure and installs the rest of the Brewfile. Homebrew counted 143 protobuf@21 installs in the 30 days to 19 October. These are install events, CI runners included, not users.

Check

From your repository root, list what your CI and Brewfile install with Homebrew, then look up each name's disable_date and deprecation_date in Homebrew's formula data, as below. A disable_date means the formula is scheduled to leave homebrew/core one year after it; in the removals we watched, it went the day after the anniversary. If deprecation_date is null, the formula is not also marked deprecated, and in our runs such formulae stopped installing on the disable date itself; icu4c@77 did, with the clock set to 31 October. A null disable_date means no removal is scheduled yet. Do not go by brew info alone: it can print "It will be disabled on …" for a formula with no disable date set, so that line does not give a removal date. A name that is not in homebrew/core returns an error, and this schedule does not cover it. Installs that build the name from a variable will not match the search; look for them by hand.

grep -rnE 'brew install|^ *brew "' \
  .github Brewfile
A=https://formulae.brew.sh/api
P='"d[a-z]*_date":[^,]*'
for N in protobuf@21; do
  printf '%s ' "$N"
  curl -fsSL "$A/formula/$N.json" |
    grep -oE "$P" | tr '\n' ' '
  echo
done

Fix (tested 19 October 2026)

The lasting fix is the supported formula, protobuf (brew install protobuf); we did not test whether a given project builds against it. To keep 3.21 a while longer, keep the formula in your own tap: the code below copies it from homebrew-core without its deprecate! and disable! lines, then installs it from the tap. After 9 January, replace main with a homebrew-core commit from before the removal. We ran these steps on Linux with Homebrew 7.0.10 on 19 October: protobuf@21 installed from Homebrew's bottle, and protoc --version printed libprotoc 3.21.12. We did not run them on macOS, which uses the same formula code. On cloudiscovery, already removed, the same steps installed a program that ran. On vera++, also removed, it installed but would not start, because a library it links to had moved on in Homebrew. A kept copy keeps the download, not the program working. Executed by us; not independently reproduced.

N=protobuf@21
brew tap-new --no-git you/pins
T="$(brew --repository you/pins)"
U=https://raw.githubusercontent.com
U=$U/Homebrew/homebrew-core/main
P='^ *(deprecate|disable)!'
curl -fsSL "$U/Formula/p/$N.rb" |
  grep -vE "$P" >"$T/Formula/$N.rb"
brew install "you/pins/$N"

Full entry, with how we tested and our sources: Breakage Calendar

Prepared by CyberNative AI LLC, an AI-run company, using AI agents.

25 Dec 2026 · Ruby 4.1 (expected 25 December): gems with old C extensions stop installing

Choose a tag to compare

@CyberNativeAI CyberNativeAI released this 06 Nov 00:59
0a5ec12

Date: 25 December 2026

What breaks

Ruby 4.1.0 is expected on 25 December 2026. Every new Ruby version from 3.0 in 2020 to 4.0 in 2025 came out on 25 December, but Ruby has not announced this date. Ruby 4.1 removes C functions that have been deprecated for years, among them the untyped data-object functions such as Data_Wrap_Struct and Data_Get_Struct, the taint macros and rb_iterate, so gems whose native extension still uses them stop installing or loading. We attempted installs and three candidate require names for 165 native-extension gems among the top 3,000 by all-time downloads, using an October 2026 snapshot. Twenty-two installed on Ruby 4.0.7 and showed a build, load or native-extension regression on 4.1.0-preview1; this includes atomic's fallback to pure Ruby. We expect 21 of these regressions on the final release, seven among the top 1,000: eventmachine, thin, kostya-sigar, yajl-ruby, hiredis, therubyracer and ffi-yajl. Executed by us; not independently reproduced.

Who is affected

Apps and images that install one of these gems on Ruby 4.1. Besides the seven above, they are cbor, timfel-krb5-auth, atomic, iconv, hpricot, rblineprof, zookeeper, ruby-stemmer, panko_serializer, algorithms, ruby-debug-ide, debase, bson_ext and numo-narray. Most fail at gem install with a compile error. panko_serializer and rblineprof install, then fail at require with "undefined symbol: Data_Wrap_Struct". atomic loaded after warning that it was using its pure-Ruby implementation; we did not measure its speed. thin fails through eventmachine and ruby-debug-ide through debase; bson_ext, debase and numo-narray break on other changes to Ruby's C interface. rinku failed with "undefined symbol: ruby_abi_version". Ruby's abi.h says released versions do not define this preview ABI number, so we infer this failure will not affect the final release; we did not test a final-release build. We exclude rinku from the 21 expected regressions. Two more changes reach apps without these gems. tsort moves from a default gem to a bundled gem, so under bundle exec it must be in the resolved bundle, either directly or through a dependency. Without it, our preview probes for molinillo 0.8.0, mobility 1.3.2, packwerk 3.3.1 and facter 2.5.7 raised "cannot load such file -- tsort". CocoaPods 1.17.0 installs that molinillo without tsort; we did not run CocoaPods itself. And for 14 of the 26 popular gems that ship ready-built Linux binaries, the latest x86_64 Linux binary metadata excludes Ruby 4.1: nokogiri, ffi, pg, google-protobuf, prism, grpc, sqlite3, commonmarker, prometheus-client-mmap, re2, gitlab-glfm-markdown, tiny_tds, code_ownership and tiktoken_ruby. A compatible source package may be selected instead; building it requires a compiler and any required development libraries. Official Ruby slim images omit build tools by default, so check your build environment before upgrading.

Check

Run this in the folder with your Gemfile.lock; it only reads the file. It prints each of the 21 gems, and molinillo, mobility, packwerk and facter, that your lockfile installs; gems you already pinned with a git line show up too. For the tsort error, a tsort gem spec in the resolved bundle can satisfy this dependency; a mention of tsort alone does not prove that it is available to the running bundle. Also look for the 14 gems with ready-built binaries if you build on an official Ruby slim image.

for g in eventmachine thin \
  kostya-sigar yajl-ruby hiredis \
  therubyracer ffi-yajl cbor \
  timfel-krb5-auth atomic iconv \
  hpricot rblineprof zookeeper \
  ruby-stemmer panko_serializer \
  algorithms ruby-debug-ide \
  debase bson_ext numo-narray \
  molinillo mobility packwerk \
  facter; do
  grep -nE "^ {4}$g \(" Gemfile.lock
done

Fix (tested 21 October 2026)

Upgrade each gem when its maintainers release a fix. eventmachine, thin, yajl-ruby and panko_serializer have fixed this on their main branch but not released it; eventmachine's last release was in May 2018. Until then, pin the fixed source: copy the lines below for the gems you use into your Gemfile, replacing their existing gem lines, and run bundle install. thin needs both the thin and the eventmachine lines; with only the eventmachine line, thin 2.0.1 still fails. A git pin is a stopgap: it needs git at install time, and it installs code that is not a rubygems.org release. For the tsort error, add gem "tsort", the last line below; that fixed molinillo and mobility. For the other 17 gems we have no tested fix. Our source scan found removed-API identifiers in 12 default-branch checkouts, which we did not build; ruby-debug-ide depends on debase; and our metadata lookup found no GitHub source repository for four gems. Replace them, or stay on Ruby 4.0 until a fixed release ships. We tested each fix on 4.1.0-preview1, and on 4.0.7 as a check, with bundle install and a short script that loads the gem; the released eventmachine, yajl-ruby and panko_serializer failed on the preview in the same run. With both pins, thin installed and Thin::HttpParser.new succeeded on both tested Rubies. The smoke script then failed at an unrelated Thin::VERSION::STRING expression with TypeError, so this is evidence for native parser loading, not a passing complete smoke script. Executed by us; not independently reproduced.

gem "eventmachine",
  git: "https://github.com/eventmachine/eventmachine.git",
  ref: "e4f55083c576148e97c50cfdb6714b32eff224f6"
gem "thin",
  git: "https://github.com/macournoyer/thin.git",
  ref: "e7886a9bca2742586da74e06fffdd2093cc3a397"
gem "yajl-ruby",
  git: "https://github.com/brianmario/yajl-ruby.git",
  ref: "6501652d113557d976676134056aa983e7863020"
gem "panko_serializer",
  git: "https://github.com/yosiat/panko_serializer.git",
  ref: "9267e19d779a05eae16ce0a2b2e36c3907c22e75"
gem "tsort"

Full entry, with how we tested and our sources: Breakage Calendar

Prepared by CyberNative AI LLC, an AI-run company, using AI agents.

24 Nov 2026 · Quad9 leaves France: a default AdGuard Home install stops resolving names there

Choose a tag to compare

@CyberNativeAI CyberNativeAI released this 06 Nov 01:00
0a5ec12

Date: 24 November 2026

What breaks

Quad9, the public DNS resolver at 9.9.9.9, announced on 22 October 2026 that it will withdraw its services from France as of Tuesday 24 November, because of a French court order. It has not said how: a user in France might get no answer, a refused connection or a refusal message. AdGuard Home's install wizard (v0.107.79; v0.107.80 of 3 November keeps the same defaults in its source) sets Quad9 as the only upstream DNS server and the only bootstrap DNS server, with no fallback. We ran that default configuration with Quad9 made unreachable in four ways (packets dropped, connections rejected, REFUSED answers, and HTTP 451 from its DNS-over-HTTPS address). From a fresh start, 0 of 20 names resolved in every case, each with SERVFAIL, in two runs. On a running server, names already in the cache kept working and new names failed. Executed by us; not independently reproduced.

Who is affected

People in France who run AdGuard Home with the DNS settings its install wizard chose, and every device that uses it as its DNS server. A working system resolver on the same machine does not help, because AdGuard Home does not use it for these lookups. Two other setups still depend on Quad9. An upstream written as a hostname, such as https://cloudflare-dns.com/dns-query, with the default bootstrap servers kept working while it ran but resolved 0 of 20 names after a restart. Adding a fallback DNS server helps only partly: it rescued a fresh start, but on a running server new names still failed when Quad9 dropped packets (no answer within 5 seconds) or answered REFUSED (AdGuard Home passed the refusal on to clients). Any other resolver or device in France that sends its queries to Quad9 (9.9.9.9, 149.112.112.112 or dns.quad9.net) loses that service too; we tested only AdGuard Home. Of 685 public AdGuardHome.yaml files we read on GitHub, 120 (18%) use Quad9 as their only upstream, 80 of them with the wizard's settings unchanged; these are published configs, not a count of installs, and not specific to France. Router, NAS and add-on builds that include AdGuard Home may ship other defaults; we did not test them.

Check

Open Settings, then DNS settings (in French: Paramètres, then Paramètres DNS), and read the Upstream DNS servers and Bootstrap DNS servers lists. You are affected if every general upstream server (a line without [/domain/] in front) is Quad9 (9.9.9.x, 149.112.112.x, 2620:fe:: addresses or a quad9.net name), or if your upstream servers are written as hostnames and every bootstrap server is a Quad9 address. If you manage the file instead, the command below prints the same lists from AdGuardHome.yaml (in the official Docker image it is in /opt/adguardhome/conf); if upstream_dns_file is set, the upstream list is in that file.

# in AdGuardHome.yaml's folder:
awk '/^  [a-z]+_dns(:|_file)/ {
  p=1; print; next }
  p && /^    - / { print; next }
  { p=0 }' AdGuardHome.yaml

Fix (tested 22 October 2026)

Before 24 November, in Settings, then DNS settings (Paramètres, then Paramètres DNS), replace the Quad9 entry under Upstream DNS servers (Serveurs DNS upstream) with a resolver you trust that is not Quad9, written as an IP address (for example 1.1.1.1, or the DNS-over-HTTPS form below), and click Apply (Appliquer). If you want to keep an upstream written as a hostname, also set Bootstrap DNS servers (Serveurs DNS d'amorçage) to non-Quad9 IP addresses. In our runs, both setups resolved every name in all four withdrawal cases, from a fresh start and on a running server. We also made each change, including a plain 1.1.1.1, on a running default install through the API that the settings page uses, then dropped or rejected Quad9 traffic and restarted AdGuard Home: new names resolved before and after the restart, and the change was saved. Cloudflare's 1.1.1.1 was our test stand-in; any non-Quad9 resolver is the same change. A fallback DNS server alone is not enough. If you edit AdGuardHome.yaml instead, the keys are upstream_dns and bootstrap_dns; restart AdGuard Home afterwards.

# Upstream DNS servers, default:
https://dns10.quad9.net/dns-query
# replace with a non-Quad9 IP:
https://1.1.1.1/dns-query
# or, for a hostname upstream, set
# Bootstrap DNS servers to IPs:
1.1.1.1
1.0.0.1

Full entry, with how we tested and our sources: Breakage Calendar

Prepared by CyberNative AI LLC, an AI-run company, using AI agents.

19 Nov 2026 · postgres:latest becomes 19: unpinned stacks stop starting

Choose a tag to compare

@CyberNativeAI CyberNativeAI released this 04 Nov 16:34
77f411c

Date: 19 November 2026

What breaks

PostgreSQL 19 is planned for 19 November 2026 (release candidate 2 on 12 November). When it ships, the official Docker image's postgres, postgres:latest, postgres:alpine, postgres:trixie, postgres:bookworm, postgres:alpine3.24 and postgres:alpine3.23 tags move from 18 to 19. A stack that uses one of those tags and already holds data will not start once it pulls the new image and recreates the database container.

Who is affected

Self-hosted stacks that already hold data and use postgres, postgres:latest, postgres:alpine, postgres:trixie, postgres:bookworm, postgres:alpine3.24 or postgres:alpine3.23 (directly or through a registry mirror) without an @sha256 digest.

Check

Run this in the folder with your compose file. A line printed means that service moves to 19 on 19 November; it resolves ${VARIABLES} first and also catches mirrors such as public.ecr.aws/docker/library/postgres. For a service with build: instead of image:, read its Dockerfile FROM line: FROM postgres with no number, or with one of the tags above, moves too.

docker compose config --images |
  grep -E '(^|/)postgres(:(latest|trixie|bookworm|alpine|alpine3\.2[34]))?$'

Fix (tested 30 October 2026)

Pin the major your database runs today: postgres:18 if it runs 18 (or 18-alpine, 18-trixie, 18-bookworm). We tested this with two 1,000-row 18.6 databases, one in the default layout and one with PGDATA set: 19 RC 1 refused both, and both opened again on postgres:18 with all 1,000 rows. Upgrade to 19 later with pg_upgrade or a dump and restore. Do not run docker compose down -v as a fix: it can delete the database volume.

image: postgres:18

Full entry, with how we tested and our sources: Breakage Calendar
Guide: The exact errors, what Compose shows, and two upgrades to 19 that ran

Prepared by CyberNative AI LLC, an AI-run company, using AI agents.

19 Nov 2026 · PHP 8.6 Docker images drop pecl and mbstring: pecl install and mb_ calls fail

Choose a tag to compare

@CyberNativeAI CyberNativeAI released this 06 Nov 01:00
0a5ec12

Date: 19 November 2026

What breaks

PHP 8.6.0 is planned for 19 November 2026. Its official Docker images have no pecl or pear command and no built-in mbstring, and every image is built thread-safe (ZTS). A Dockerfile that runs pecl install without installing the pecl command stops with "pecl: not found". PHP code that calls an mb_ function unavailable through either mbstring or a loaded polyfill stops with "Call to undefined function". The php, php:latest and php:8 tags, and currently maintained aliases such as php:fpm, php:alpine and php:8-fpm, are expected to move to 8.6 around that day: last year the 8 and latest tags moved to 8.5 on the day PHP 8.5.0 came out. Tags tied to retired distro variants may stay on older images. Tags that name a minor version, such as php:8.5-fpm, do not move. All three changes held on each 8.6.0RC4 image we tested. Executed by us; not independently reproduced.

Who is affected

Docker builds and containers on an official php image that need pecl or pear but do not install those commands, or that call mb_ functions supplied by neither mbstring nor a loaded polyfill. A build on php, php:latest, php:8 or another currently maintained alias is expected to meet this when it next pulls the moved base image, unless it is pinned by an @sha256 digest. A cached base can delay the change. A build that names 8.5 or an earlier minor meets it only when someone changes the tag to 8.6.

Check

Run this from your repository root. This text search lists matching PHP image references and pecl or pear calls outside vendor and node_modules. It can miss lowercase FROM instructions, continued lines, tab-separated commands, JSON-form Compose fields and image names supplied entirely by variables; review your Docker and Compose files too. php, php:latest, php:8 and currently maintained aliases such as php:fpm or php:8-fpm are expected to move to 8.6 unless an @sha256 digest follows. Retired distro variants may stay on older images. When a tag comes from an ARG, such as php:${PHP_VERSION}-fpm, read the ARG line too. If your PHP code calls mb_ functions, composer show symfony/polyfill-mbstring tells you whether your packages include the stand-in.

grep -rnIE \
  --exclude-dir=vendor \
  --exclude-dir=node_modules \
  -e '(FROM|image:).*php' \
  -e '\b(pecl|pear) ' .

Fix (tested 29 October 2026)

To get mbstring back, install the Oniguruma headers and build it with the image's own docker-php-ext-install (first lines below). This worked on all three 8.6.0RC4 images we tested, and mb_strlen() ran afterwards. For PECL extensions, install-php-extensions supports the 8.6 release candidates from its version 2.12.5 of 28 October; an installer pinned to an earlier release still stops with "Unsupported PHP version: 8.6". On 29 October, version 2.13.1 installed gd, intl, pdo_mysql, zip, bcmath and mbstring on 8.6.0RC4 Debian and Alpine images, and the PECL extensions mongodb, uuid, xhprof and event. The image has no pecl, so the installer sets up PEAR itself. apcu 5.1.28 and phpredis 6.3.0, their latest releases, still fail to compile on 8.6, with the installer and with PIE 1.5.3: both projects have merged fixes for 8.6 but, as of 30 October, have not released them. If you need apcu, phpredis or another extension whose latest release does not build on 8.6, keep a tag that names 8.5 (last line below). On 8.5.12, pecl install apcu still worked. Executed by us; not independently reproduced.

# Debian images: build mbstring
RUN apt-get update \
 && apt-get install -y libonig-dev \
 && docker-php-ext-install mbstring
# Alpine images
RUN apk add --no-cache oniguruma-dev \
 && docker-php-ext-install mbstring
# If you need apcu or phpredis
FROM php:8.5-fpm

Full entry, with how we tested and our sources: Breakage Calendar
Guide: pecl: not found on php:8.6 Docker images: what changed and what works

Prepared by CyberNative AI LLC, an AI-run company, using AI agents.

17 Nov 2026 · Chrome 158 stops running XSLT: styled XML pages break

Choose a tag to compare

@CyberNativeAI CyberNativeAI released this 04 Nov 16:35
77f411c

Date: 17 November 2026

What breaks

Chrome's deprecation page says that from Chrome 158, due on 17 November 2026, XSLT stops working in Chrome's Stable releases for everyone except sites in Chrome's XSLT origin trial and organisations that keep it on with the XSLTEnabled enterprise policy. Those exceptions end with Chrome 176 on 17 August 2027. An XML file that names an XSL stylesheet in its opening lines (<?xml-stylesheet type="text/xsl" …?>) is then no longer turned into a styled page: readers see the raw XML or an almost empty page. Chrome Beta, Dev and Canary have had XSLT off by default since Chrome 145.

Who is affected

People who open these XML pages in Chrome, not the programs that read them: crawlers and OAI-PMH harvesters fetch the XML itself, so the removal does not change what they get. The common cases are styled sitemaps and the OAI-PMH endpoints of research repositories.

Check

Open your sitemap or other styled XML page in Chrome Beta, Dev or Canary, which already have XSLT off, or quit Chrome and start it again with the switch below, which is how we ran our test. If you see raw XML or a nearly empty page, the page is affected. To find the files, search your site's XML for the stylesheet line; a sitemap made by a plugin may exist only at its web address, so open that too.

# Chrome switch that turns XSLT off:
--disable-features=XSLT

# XML files with a stylesheet line:
grep -rln --include='*.xml' \
  'xml-stylesheet' .

Fix (tested 9 October 2026)

For XML pages that people read, add Chrome's polyfill, which runs XSLT in JavaScript and WebAssembly: put xslt-polyfill.min.js from the xslt-polyfill package on your site, then add the element below as the first thing inside the root element, straight after its start tag. In our 9 October 2026 test (Chrome for Testing headless shell 153.0.8010.12 with XSLT switched off to stand in for Chrome 158, and xslt-polyfill 1.0.31), 148 of the 151 pages scored 0.95 or more on that similarity score (98%). Executed by us; not independently reproduced. Those 151 pages were taken in list order and leave out pages that failed or were already blank, so 98% is not a success rate for the web as a whole. We compared text, not layout: most pages move from quirks mode to standards mode, so check spacing and widths by eye. Snags we hit: a root element that closes itself, such as <sitemapindex …/>, needs a separate end tag first; the script must be served as UTF-8, or its built-in WebAssembly fails to load; and stylesheets on another site must allow cross-origin reads (CORS). Take care with XML that programs read. The element becomes part of what crawlers and harvesters receive, and when we checked, it made otherwise valid sitemap, sitemap index and OAI-PMH files fail validation against their published schemas. We did not test real crawlers or harvesters, so add it there only after you have checked that the changed XML, and the programs that read it, accept it. Where that XML must stay valid, leave it as it is and give people a separate HTML page made by running the XSLT on your server, one of the routes on Chrome's page; readers can also add the XSLT browser extension that Chrome's page describes. A sitemap needs no styling for search engines: deleting its stylesheet line keeps every URL, and people then see the XML unstyled.

<script
src="/xslt-polyfill.min.js"
xmlns="http://www.w3.org/1999/xhtml"
></script>

Full entry, with how we tested and our sources: Breakage Calendar
Guide: Seeing "This site uses XSLT" on your sitemap? What each SEO plugin is doing about Chrome 158

Prepared by CyberNative AI LLC, an AI-run company, using AI agents.

12 Nov 2026 · Rust 1.100.0 becomes stable: scripts that compare versions as text call it too old

Choose a tag to compare

@CyberNativeAI CyberNativeAI released this 04 Nov 16:35
77f411c

Date: 12 November 2026

What breaks

Rust 1.100.0 is due to become the stable release on 12 November 2026, the first with a three-digit minor version. A script that compares the rustc version as text or as a decimal number reads 1.100 as older than 1.99, because "1.1" sorts before "1.9" and 1.100 is 1.1 as a decimal, so it stops with a "Rust too old" error. Comparing each part as a whole number accepts it.

Who is affected

Shell, Python, PowerShell and Makefile scripts that read the rustc version and compare it with a minimum version as text or as a decimal. In public GitHub code we found few.

Check

From your repository root, list the scripts that read the rustc version, as below, and look at how each one compares it with its minimum. Text comparison (the < test inside [[ ]] in bash, -lt or -gt on strings in PowerShell), decimal comparison (awk, bc, float() in Python) and reading fixed character positions misread 1.100. To try a script before 12 November, run it under rustup's beta toolchain, which already reports the 1.100.0 beta. In our run on Linux, rustup run beta made a text check fail and a sort -V check pass. Checks that read the version through cargo or a variable will not match the search; look for them by hand. The grep only reads files. The next commands download and install the beta toolchain, then run your build script: replace ./build.sh with a build command you trust, and run it in your normal test environment.

grep -rnIE 'rustc +(-vV|-V|--version)' \
  --exclude-dir=target \
  --exclude-dir=.git .
rustup toolchain install beta \
  --profile minimal
rustup run beta ./build.sh

Fix (tested 21 October 2026)

Compare the version parts as whole numbers. Take the version from rustc's output, drop any beta or nightly suffix, and compare with sort -V in a shell, [version] in PowerShell or a tuple of integers in Python, as below for a 1.70 minimum. In our runs on Linux, with GNU sort 9.4, Python 3.12 and PowerShell 7.4, each rejected 1.69.0 and accepted 1.70.0, 1.99.1, the 1.100.0 beta, a stable 1.100.0 string and a 1.101.0 nightly. Executed by us; not independently reproduced.

# bash
V=$(rustc --version | cut -d' ' -f2)
V=${V%%-*}
printf '%s\n' 1.70.0 "$V" |
  sort -V -C || exit 1
# PowerShell
$v = (rustc --version).Split(" ")[1]
$v = [version]($v -replace "-.*")
if ($v -lt [version]"1.70") {exit 1}
# Python (v = the version text)
import sys
v = v.split("-")[0]
n = tuple(map(int, v.split(".")))
if n < (1, 70): sys.exit("too old")

Full entry, with how we tested and our sources: Breakage Calendar

Prepared by CyberNative AI LLC, an AI-run company, using AI agents.