Cloud & DevOpsSecurityDeveloper ToolsNews & Analysis

GitHub Actions Self-Hosted Runners: Fix Before September 25

GitHub Actions self-hosted runner pipeline showing outdated runner nodes with warning indicators and a September 25 enforcement deadline countdown
GitHub Actions self-hosted runner enforcement: brownouts are live, hard stop September 25

GitHub’s self-hosted runner enforcement isn’t approaching — it arrived. Brownouts went live today (September 14), and the hard cutoff is September 25. After that date, any self-hosted runner not updated within 30 days of the latest release stops receiving jobs. The failure is silent: no error in your workflow, just jobs sitting in Queued indefinitely.

If your CI was flaky this morning, this might be why.

What Is Happening and Why

GitHub rebuilt the Actions backend from scratch. The old platform handled roughly 23 million jobs per day. The new one handles 120 million or more — more than five times the previous volume — and enables enterprises to start seven times more jobs per minute. Old runner versions cannot communicate with the new infrastructure. This is a hard technical incompatibility, not a policy choice.

GitHub set a minimum version (2.329.0) and a rolling rule: runners must update within 30 days of any new release, or they stop receiving jobs. The enforcement has been extended twice — from December 2025 to March 2026, then to September 2026. There are no more extensions on the table.

The Brownout Schedule

GitHub is running brownouts before the hard deadline. On brownout days, outdated runners intermittently fail to register and stop executing jobs. The official enforcement timeline lists the remaining windows:

  • September 14 — today
  • September 16
  • September 18
  • September 25 — hard enforcement, no jobs queued to outdated runners

GitHub Enterprise Server (on-premise GHES) is not affected. GitHub Enterprise Cloud with Data Residency already hit full enforcement on July 31.

Who Is Actually at Risk

Most runners auto-update by default. If you haven’t explicitly disabled updates, there is a good chance you are already fine. The real danger is runners that opted out of automatic updates:

  • Runners launched with --disableupdate — common in Docker images, Helm charts, and Terraform configs written months ago. The flag is often buried and forgotten.
  • Container-based runners (Kubernetes/ARC) — the runnerVersion field in a RunnerDeployment or AutoscalingRunnerSet spec must be bumped explicitly.
  • Air-gapped runners — cannot auto-download updates; require a manual process every time a new release ships.
  • Orphaned runners — set up by someone who has since left the team, pinned to an old version, and never revisited.

The --disableupdate flag was a reasonable choice for teams that wanted control over their runner environment. It now creates mandatory maintenance overhead: you must update within 30 days of each release, by hand. That is a worse tradeoff than auto-updates for most teams.

How to Check Your Runners

The September 3 changelog shipped a new REST API specifically for this:

GET /actions/runners/deprecations/{version}

Call it at the repository, organization, or enterprise level. The response returns runtime_deprecates_at and registration_deprecates_at for the version you query — exact dates, no guessing.

To list all runners in an org with their versions:

gh api /orgs/ORG/actions/runners \
  --jq '.runners[] | {name: .name, version: .version}'

You can also check via Settings → Actions → Runners in the GitHub UI — click any runner to see its version.

How to Fix It

If your runners auto-update, they should already be current. Verify and move on.

If you have runners with --disableupdate:

  1. Stop the runner service.
  2. Download the latest release from the runner releases page.
  3. Extract, re-configure, and restart.

For actions-runner-controller (ARC) users: set runnerVersion: latest in your AutoscalingRunnerSet spec or pin to a version above 2.329.0, then redeploy.

Two More Changes from September 3

The same changelog that shipped the deprecation API also added two improvements worth knowing:

vulnerability-alerts permission for GITHUB_TOKEN. Workflows can now read Dependabot alerts with a scoped permission — no PAT required:

permissions:
  vulnerability-alerts: read

The previous workaround — a classic personal access token with security_events scope stored as a repo secret — created a rotation risk. This eliminates that.

New job context properties for reusable workflows. Four new fields (job.workflow_ref, job.workflow_sha, job.workflow_repository, job.workflow_file_path) let reusable workflows verify their own source identity at runtime. Useful for supply chain integrity checks and audit trails.

The Checklist

  1. Audit runner versions — Use the new API or the GitHub UI to find runners below 2.329.0 or not updated within 30 days.
  2. Find and remove --disableupdate — Search your Docker images, Helm charts, Terraform modules, and systemd units.
  3. ARC users: bump runnerVersion — Set to latest or pin above 2.329.0 and redeploy before September 25.

Eleven days left. The brownouts have already started. Check your runners before the next window hits on September 16.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *