What Breaks When ubuntu-latest Moves to Ubuntu 26.04 in GitHub Actions
Table of Contents
GitHub is moving the ubuntu-latest label from Ubuntu 24.04 to Ubuntu 26.04: the rollout began on October 19, 2026 and GitHub says it will finish on November 19. If your workflow says runs-on: ubuntu-latest, during these weeks some jobs already run on 26.04 and others still on 24.04, so a failure that comes and goes without you touching anything has an obvious suspect. What changes underneath is a lot: kernel 7.0, Node 24 by default, PHP 8.5, Python 3.14, Docker 29, Java 25 and eleven tools that are no longer preinstalled.
The emergency fix fits on one line (runs-on: ubuntu-24.04) and comes from GitHub’s own notice. What follows is so you know what breaks before deciding whether to pin the version or migrate. Everything comes from the notices and the image README in actions/runner-images, checked on November 13, 2026; where something is an open user report rather than a GitHub decision, I say so.
The calendar
| Date | What happened or happens | Source |
|---|---|---|
| Jun 11, 2026 | Ubuntu 26.04 and 26.04 Arm in public preview | #14226 |
| Sep 17, 2026 | General availability: ubuntu-26.04 and ubuntu-26.04-arm labels | #14747 |
| Sep 17, 2026 | Notice that ubuntu-latest will move to 26.04 | #14748 |
| Oct 19, 2026 | Gradual rollout of ubuntu-latest begins | #14748 |
| Nov 19, 2026 | Planned end of the migration | #14748 |
| Apr 17, 2027 | ubuntu-22.04 is retired | #14254 |
The notice is about the x64 ubuntu-latest label; pinned labels (ubuntu-24.04, ubuntu-26.04) don’t change meaning. It’s the same mechanic as what broke in GitHub Actions this fall: the notice comes weeks ahead and almost nobody reads it until a job fails.
What changes in the image
The table compares the Ubuntu 24.04 README (image 20261111) with the Ubuntu 26.04 one (image 20261101). Exact versions change with every weekly image; what matters is the major-line jump.
| Component | Ubuntu 24.04 | Ubuntu 26.04 |
|---|---|---|
| OS | 24.04.5 LTS | 26.04.1 LTS |
| Kernel | 6.17 | 7.0 |
| systemd | 255 | 259 |
| Default Node.js | 22.23.4 | 24.22.2 |
| PHP | 8.3.6 | 8.5.4 |
| Python | 3.12.3 | 3.14.4 |
| Ruby | 3.2.3 | 3.3.8 |
| Perl | 5.38.2 | 5.40.1 |
| Docker (client and server) | 28.0.4 | 29.4.2 |
| Docker Compose | 2.38.2 | 5.1.3 |
| GCC | 13.2 | 15.2 |
| Default Java | 17 | 25 |
p7zip-full | 16.02 | replaced by 7zip 26.00 |
Kernel and systemd numbers are the ones GitHub gives in notice #14748; the rest come from each image’s README.
What breaks, by impact
1. Default Java goes from 17 to 25, and Java 8 is gone
The notice is blunt: “Default version updated to Java 25”. A Maven or Gradle build that doesn’t declare a version (no actions/setup-java) no longer compiles with 17. Also, the 26.04 JDK list is 11, 17, 21 and 25: there is no JAVA_HOME_8_X64, while 24.04 did ship a Java 8. The fix is the usual one and works on any image: declare the version.
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
2. Docker 29 and Compose 5
Docker goes from 28.0.4 to 29.4.2 and Compose from 2.38.2 to 5.1.3. I haven’t tested your pipelines, but two open reports are worth knowing:
- i386 containers with no network. In #14790 a user reports that Docker 29.4.2 ships a seccomp profile that blocks
socketcall(2); i386 images on glibc can’t resolve names. Per the report, Docker 29.4.3 or later reverts it. musl-based images (i386/alpine) aren’t affected. It’s a user report, not a GitHub note; today’s README still lists 29.4.2. - Disk space. In #15233 someone reports that a
docker buildwith a large layer ran out of space onubuntu-latestduring the rollout and finished after pinningubuntu-24.04. It’s a single open case with no confirmed cause: don’t take it as fact, but if your big image builds start failing with “no space left on device”, that’s the first place to look.
3. Default Node, PHP and Python move a major line
If your job uses the system node, php or python3 instead of setup-node, setup-php or setup-python, it now runs Node 24, PHP 8.5 and Python 3.14. A project on Laravel 12 runs fine on PHP 8.5 (Laravel 12 supports 8.2 to 8.5, per the release notes), but one with dependencies that don’t declare 8.5 can fail at composer install. The fix is to stop relying on the default: shivammathur/setup-php with php-version: '8.3' and actions/setup-node with node-version: 22 or 26 (what changes in Node 26).
4. Tools no longer preinstalled
Comparing the two READMEs, these eleven disappear from 26.04: Fastlane, Haveged, Julia, Lerna, MediaInfo, Mercurial, Miniconda, Newman, Parcel, Pulumi and Sphinx Open Source Search Server. I found no GitHub notice listing them; it’s the result of diffing the two READMEs’ tool lists on November 13, so if one is missing from my list it’s because I didn’t detect it. A lerna run or pulumi up that used to “just work” now gives command not found; install it in the job (npm i -g lerna, pulumi/actions, etc.).
One system-package detail: p7zip-full and p7zip-rar became 7zip and 7zip-rar. If your workflow runs apt-get install p7zip-full, check the package still exists on 26.04 or switch it to 7zip.
5. Finer system details
/etc/sysctl.confisn’t applied at boot. #15108 (open): the image writesfs.inotify.max_user_instances=1280andmax_user_watches=655360, but on 26.04 the kernel keeps 128 and 64097 because systemd no longer reads that file. If a file watcher (Vite, Jest in watch mode, webpack) fails withENOSPCor “too many open files”, this is it. Your job can raise them withsudo sysctl -w.setfaclfails. #15004 (open) reports it breakingopenai/codex-action.- Rootless Podman has AppArmor reports (#15184, #15182). If you use Podman instead of Docker, read both.
- Azure DevOps: the agent user changed from
vststorunner(#15028); it affects/home/...paths. It doesn’t touch standard GitHub Actions.
How to know if you’re affected
# Workflows using ubuntu-latest (the affected ones)
grep -rn "ubuntu-latest" .github/workflows/
# Across an organization, with the GitHub CLI
gh search code "ubuntu-latest" --owner YOUR_ORG --filename "*.yml" --limit 100
To see which system a job actually ran on, add a first step to the workflow: cat /etc/os-release | grep VERSION=. During the rollout, the same workflow can give 24.04 today and 26.04 tomorrow.
What to do
- Test on 26.04 now without touching the main workflow: a copy with
runs-on: ubuntu-26.04(GitHub recommends it in the notice to test the new image explicitly). - If it fails and you have no time: pin
runs-on: ubuntu-24.04. It’s the escape hatch the notice itself offers. It isn’t a permanent fix: a pinned label stops getting new images someday, and I found no retirement date for 24.04 in today’s notices, so check actions/runner-images from time to time. - Declare explicit versions of Java, Node, PHP and Python with the
setup-*actions. It’s what keeps the nextubuntu-latestchange from surprising you. - Stop depending on preinstalled tools that aren’t in common use: install them in the job.
This site’s CI runs on ubuntu-latest (with a configurable fallback) and declares Node 24 with actions/setup-node, so it doesn’t depend on the system Node: it’s the rule I apply, nothing that matters is inherited from the image.
Frequently asked questions
When does ubuntu-latest move to Ubuntu 26.04?
GitHub began the gradual rollout on October 19, 2026 and plans to finish on November 19, 2026, per notice 14748 in actions/runner-images. While it lasts, the same workflow can run on 24.04 or on 26.04.
How do I stay on Ubuntu 24.04?
Change runs-on: ubuntu-latest to runs-on: ubuntu-24.04. It is the mitigation GitHub proposes in the notice. To try the new image without migrating everything, use runs-on: ubuntu-26.04 in a copy of the workflow.
Which Node, PHP and Python versions does Ubuntu 26.04 ship on GitHub Actions?
Per the image README of November 1, 2026: Node.js 24.22.2, PHP 8.5.4 and Python 3.14.4 (Ubuntu 24.04 ships Node 22.23.4, PHP 8.3.6 and Python 3.12.3). To avoid depending on the default, use setup-node, setup-php and setup-python.
Which tools were removed from the Ubuntu 26.04 image?
Comparing the 24.04 README with the 26.04 one on November 13, 2026, Fastlane, Haveged, Julia, Lerna, MediaInfo, Mercurial, Miniconda, Newman, Parcel, Pulumi and Sphinx Open Source Search Server no longer appear. GitHub did not publish that list in a notice; it is the result of the comparison.
Does ubuntu-latest also change on ARM runners?
Notice 14748 is about the x64 ubuntu-latest label. The ubuntu-26.04 and ubuntu-26.04-arm labels have existed since September 17, 2026 and can be used explicitly at any time.
Found it useful? Get the next one by email
Once a week: what breaks when you upgrade, AI for developers and what I'm building, with sources. No spam.
By subscribing you accept our privacy policy.