What Breaks When ubuntu-latest Moves to Ubuntu 26.04 in GitHub Actions

Typographic cover on a dark green background: ubuntu-latest and Ubuntu 26.04 in large letters above a two-line diff swapping ubuntu-24.04 for ubuntu-26.04
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

    DateWhat happened or happensSource
    Jun 11, 2026Ubuntu 26.04 and 26.04 Arm in public preview#14226
    Sep 17, 2026General availability: ubuntu-26.04 and ubuntu-26.04-arm labels#14747
    Sep 17, 2026Notice that ubuntu-latest will move to 26.04#14748
    Oct 19, 2026Gradual rollout of ubuntu-latest begins#14748
    Nov 19, 2026Planned end of the migration#14748
    Apr 17, 2027ubuntu-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.

    ComponentUbuntu 24.04Ubuntu 26.04
    OS24.04.5 LTS26.04.1 LTS
    Kernel6.177.0
    systemd255259
    Default Node.js22.23.424.22.2
    PHP8.3.68.5.4
    Python3.12.33.14.4
    Ruby3.2.33.3.8
    Perl5.38.25.40.1
    Docker (client and server)28.0.429.4.2
    Docker Compose2.38.25.1.3
    GCC13.215.2
    Default Java1725
    p7zip-full16.02replaced 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 build with a large layer ran out of space on ubuntu-latest during the rollout and finished after pinning ubuntu-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.conf isn’t applied at boot. #15108 (open): the image writes fs.inotify.max_user_instances=1280 and max_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 with ENOSPC or “too many open files”, this is it. Your job can raise them with sudo sysctl -w.
    • setfacl fails. #15004 (open) reports it breaking openai/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 vsts to runner (#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

    1. 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).
    2. 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.
    3. Declare explicit versions of Java, Node, PHP and Python with the setup-* actions. It’s what keeps the next ubuntu-latest change from surprising you.
    4. 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? Share it

    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.

    Search

    Tags

    Migration PHP AI Laravel JavaScript Tutorial Security Web Development Upgrade Best Practices SEO TypeScript OpenAI Backend Claude