Skip to content
Latchkey LogoLatchkey home

GitHub Actions deprecations: what breaks, when, and the fix

GitHub Actions deprecations arrive as a warning, spend a few months as slower queues and scheduled brownouts, and end as a job that terminates with an error. This page tracks the ones in flight with the date each takes effect, read from the announcements on 2026-09-20.

Timeline of GitHub Actions retirements from September 2026 to April 2027, with what is already gone
Dates from the actions/runner-images announcements, read 2026-09-20. A deprecation warns; a retirement fails the job.

The distinction that matters on this page is between a deprecation and a retirement. A deprecation is the announcement plus the warnings: your workflow still runs, and GitHub tells you it will not forever. A retirement is the date the label or the runtime stops working, and on that date a job naming it terminates with an error rather than degrading.

Between those two dates GitHub usually runs brownouts, which are scheduled windows where jobs using the deprecated thing fail on purpose so that a team with no dashboard finds out anyway. They are the most useful signal in the whole process and the one most often mistaken for an outage.

How to read this page, and how often it is wrong

Everything below was read from its source on 2026-09-20 and carries a link so you can check it rather than trust this page. It is refreshed monthly by rule, because the announcements arrive continuously and a tracker that is six weeks stale is worse than no tracker: it gives a team a reason not to look.

One thing to internalize about the schedule: GitHub maintains "the latest two stable versions of any given OS version", which is the sentence that appears in every image deprecation announcement. That is the rule generating all of these dates, so a new Ubuntu or macOS release going generally available is also the clock starting on the oldest one.

Runner images

A retired image label is a hard failure, not a fallback. Workflows naming one are terminated with an error.

Image labelDeprecation beginsFully unsupportedMove to
ubuntu-22.04, ubuntu-22.04-arm17 September 202617 April 2027ubuntu-24.04, ubuntu-26.04 or ubuntu-latest (#14254)
macos-14, macos-14-large, macos-14-xlarge6 July 20262 November 2026macos-15, macos-26 or macos-latest (#13518)
macos-1322 September 20254 December 2025Already retired (#13046)
ubuntu-20.041 February 202515 April 2025Already retired (#11101)
windows-20191 June 202530 June 2025Already retired (#12045)
macos-127 October 20243 December 2024Already retired (#10721)

Labels that move under you

A -latest label is not a pin and was never meant to be one. It points at the newest image GitHub considers generally available, and it is migrated on a schedule that is announced but easy to miss, because nothing in your workflow file changes when it happens.

ubuntu-latest is mid-migration right now. The announcement of 17 September 2026 says the move from Ubuntu 24.04 to 26.04 begins on 19 October 2026 and is planned to complete by 19 November 2026, rolled out over several weeks. The kernel goes from 6.17 to 7.0 with it, and workflows depending on a package version, system library, compiler or prebuilt binary from 24.04 are the ones that notice. macos-latest already moved to macos-26 between 15 June and 15 July 2026, and windows-11-arm starts moving to the Visual Studio 2026 image tomorrow, 21 September 2026, completing by the 30th.

The fix is a decision rather than a command. If a version matters to your build, name it: runs-on: ubuntu-24.04. If it does not, ubuntu-latest is correct and the migration is somebody else's problem. What does not work is ubuntu-latest plus an assumption about which release it is.

.github/workflows/ci.yml
# Moves without asking, over one to two months
runs-on: ubuntu-latest

# Pins the OS release. The image build underneath still rolls forward
runs-on: ubuntu-24.04

Actions, runtimes and workflow commands

These deprecations are about what your workflow calls rather than what it runs on. Two of them have no removal date at all, which is its own kind of trap: the warning stays survivable until suddenly it is not.

What is deprecatedStatus on 2026-09-20The fix
Actions declaring using: node20Warning only. An end-of-job annotation says the actions "are running on Node.js 20 and may not work as expected". No removal date announcedMove to node24, the current runtime, or upgrade the action. See actions/runner#4295
set-output and save-state workflow commandsDeprecated 11 October 2022. Removal was planned for 1 June 2023 and postponed on 24 July 2023 over usage. Still functionalWrite to the $GITHUB_OUTPUT and $GITHUB_STATE files
actions/upload-artifact@v3 and download-artifact@v3Closed down 30 January 2025. v1 and v2 went earlierv7 of upload-artifact and v8 of download-artifact are current. v4 introduced the breaking changes
Older actions/cache majorsv1 and v2 fail: the cache service rewrite landed 1 February 2025 and the legacy service was sunset the same day (README)v6 is current. v5 and above run on Node 24 and need runner 2.327.1 or newer
Go 1.23 and earlier in the toolcacheRemoved from the images from 22 June 2026. 1.24, 1.25 and 1.26 remain (#14237)Nothing, if you use actions/setup-go: it downloads what the toolcache no longer holds, more slowly
Android NDK 28 on the imagesRemoved from 1 October 2026, NDK 30 added. The installed set becomes 27, 29 and 30 and the default stays 27 (#14745)Nothing, unless a workflow names NDK 28 explicitly. The default $ANDROID_NDK is unchanged, so only a pinned 28 breaks

The current majors, read today

Half of staying ahead of deprecations is simply not being three majors behind. These were read from the GitHub API on 2026-09-20 and are the current releases of the actions most workflows use. If your workflow names a lower major, nothing is broken today and the gap is where the next forced migration will find you.

Pin to the major while you are reading warnings, and to a full commit SHA for anything outside your organization once you are not. GitHub Actions security covers why the SHA matters and what it costs.

.github/workflows/ci.yml
- uses: actions/checkout@v7          # v7.0.1, 20 July 2026
- uses: actions/setup-node@v7        # v7.0.0, 14 July 2026
- uses: actions/cache@v6             # v6.1.0, 26 June 2026
- uses: actions/upload-artifact@v7   # v7.0.1, 10 April 2026
- uses: actions/download-artifact@v8 # v8.0.1, 11 March 2026
- uses: actions/setup-python@v7      # v7.0.0, 20 July 2026
- uses: actions/setup-java@v6        # v6.0.1, 9 September 2026

How to stay ahead without reading changelogs

Deprecation warnings appear in the run log and in the job summary, and they are the cheapest signal available because they arrive months early and name the thing. Treat them as work rather than as decoration: one a month, in the same place you handle dependency updates, is enough to never be caught by a retirement.

Dependabot handles the action versions if you let it, including SHA pins, which it updates the same way it updates package versions. What it does not cover is the runner image labels, because those are not dependencies in any file it reads. Those need either a -latest label and a tolerance for movement, or a pinned label and a calendar entry, and the table above is the calendar.

The last piece is knowing what you actually use. A quick search across your workflows for runs-on: and for uses: majors takes a minute and usually finds a repository nobody has opened since 2024, which is exactly the one that will fail during a brownout.

Terminal
# Every runner label and action major in the organization
gh search code --owner ORG --filename "*.yml" "runs-on:" --limit 200
grep -rhoE "uses: [a-z0-9-]+/[a-z0-9-]+@v[0-9]+" .github/workflows | sort | uniq -c | sort -rn

Key takeaways

  • A deprecation warns; a retirement terminates the job with an error. Track both dates.
  • ubuntu-22.04 is unsupported from 17 April 2027, with brownouts from 23 March 2027.
  • ubuntu-latest moves to Ubuntu 26.04 between 19 October and 19 November 2026.
  • Node 20 actions are warning-only with no removal date, which is why they persist.
  • Dependabot covers action versions and not runner labels: the labels need a calendar.

Frequently asked questions

Is actions/cache v3 deprecated in 2026?
Not in the sense that it stops working. When the cache service was rewritten and the legacy service sunset on 1 February 2025, the versions that fail are v1 and v2; the README told people to upgrade to v4 or v3, so v3 is on the supported side of that line. It is four majors behind, which is the real argument for moving: v6 is current as of 26 June 2026, and v5 and above run on Node 24 and need Actions runner 2.327.1 or newer, which matters if you self-host.
When do the ubuntu-22.04 runner images stop working?
Deprecation began on 17 September 2026 and the images are fully unsupported from 17 April 2027 for both GitHub Actions and Azure DevOps. Between those dates expect longer queues at peak and four scheduled brownouts in late March and early April 2027 where jobs on that label fail deliberately. Move to ubuntu-24.04 or ubuntu-26.04.
When does ubuntu-latest become Ubuntu 26.04?
The rollout begins on 19 October 2026 and GitHub plans to complete it by 19 November 2026, spread over several weeks so that not every repository moves at once. The kernel changes from 6.17 to 7.0 alongside the userspace. If your build depends on a specific package version, compiler or prebuilt binary from 24.04, pin runs-on: ubuntu-24.04 before October.
Why does my workflow warn that actions are running on Node.js 20?
Because an action in the run declares using: node20 in its metadata and the runner now annotates that at the end of the job. It is a warning with no announced removal date, and the action itself is what has to change, not your workflow. Upgrading the action to a version built for node24 clears it; actions/runner#4295 documents the annotation, including a case where it fires inaccurately.

Related guides

References

Whoever runs the job, the image decides what breaks. Latchkey publishes what is on its runners. Start free → 30-day trial · No credit card