GitHub Actions Self-Hosted Runners: Fix Your Version Before the September 25 Enforcement

GitHub Actions Self-Hosted Runners: Fix Your Version Before the September 25 Enforcement

If your CI/CD pipeline runs on self-hosted GitHub Actions runners, GitHub has already started intermittently blocking outdated ones. Brownouts began August 24, 2026 on github.com and GitHub Enterprise Cloud, and they escalate on a fixed schedule until full enforcement locks out unsupported runners permanently on September 25, 2026. This isn't a future warning โ€” it's already happening, on and off, for four hours a day, and the blocked window gets wider and more frequent each week.

What's actually being enforced

GitHub is enforcing a minimum version for self-hosted runners on github.com and GitHub Enterprise Cloud (Data Residency editions already hit full enforcement on July 31, 2026). Two separate thresholds apply:

  • Registration minimum: v2.329.0 or later. A runner below this version cannot register or re-register with GitHub at all, once enforcement is active for it.
  • Job execution minimum: install each new runner release within 30 days of its publication. Even an already-registered runner that falls more than 30 days behind the latest release stops picking up jobs โ€” it doesn't need to fail registration to be blocked, it can just go stale in place.

This is GitHub's second attempt at this rollout. The original enforcement, first announced in December 2025, was extended in February 2026 and then paused entirely in March 2026 because too many organizations weren't ready. GitHub's stated reason for pausing was to "ensure a smooth transition" rather than break CI for everyone at once โ€” but the underlying backend rearchitecture this enforces (GitHub says Actions now handles over 120 million jobs a day) hasn't gone away, and the June 2026 changelog post made clear this time the dates are final.

The brownout schedule for github.com / GitHub Enterprise Cloud

All brownouts run 11:00 AMโ€“3:00 PM ET on the listed dates. Outside those windows, even outdated runners behave normally right up until September 25 โ€” which is exactly what makes this dangerous: a team that only checks CI health outside the brownout window can miss weeks of warning signs.

DateWhat's blocked
Aug 24Registration only
Aug 31Registration only
Sep 2Registration only
Sep 7Registration only
Sep 9Registration + job execution
Sep 11Registration only
Sep 14Registration + job execution
Sep 16Registration + job execution
Sep 18Registration + job execution
Sep 25Full, permanent enforcement โ€” no more brownout windows

Notice the pattern: the first two weeks only block new registrations (so an already-running old runner still executes jobs fine), but starting September 9 the brownouts start intermittently killing job execution on runners that are already registered and were previously working. By the third week of September, job-execution blocks happen on 4 of the last 5 brownout dates before full enforcement.

Why this breaks CI in a confusing way

Because brownouts are time-boxed and intermittent, the failure mode teams actually hit isn't "CI is down," it's "CI randomly fails between 11 AM and 3 PM ET on some days, but not others, and re-running the job fixes it." That's a much harder signal to triage than a hard outage โ€” it looks like flaky infrastructure, not a version problem, unless someone already knows to check runner versions. If your team is seeing sporadic This job was not run because the runner is offline or connection-timeout style Actions failures clustered in that ET window since August 24, this is very likely the cause, not a networking or capacity issue with your runner fleet.

How to check and fix your runner version

1. Check your current runner version. From the runner's install directory:

1./run.sh --version
2# or
3./config.sh --version

2. Check what's actually registered, at scale. If you manage runners across many repos or an org/enterprise, don't rely on spot-checking individual machines. Two options:

  • The REST API for self-hosted runners now returns version data per runner โ€” script a sweep across your org/enterprise runner list rather than checking box by box.
  • Enterprise/org owners can query the audit log for registration events (org.register_self_hosted_runner, repo.register_self_hosted_runner, enterprise.register_self_hosted_runner) to see what versions have been registering recently.

3. Upgrade. Download the latest release from actions/runner releases (as of this writing, well above the 2.329.0 floor โ€” GitHub ships new runner versions roughly monthly, so "latest" comfortably clears both the registration and 30-day job-execution thresholds). Re-run your existing config.sh against the new binary, or rebuild the VM image / container image your runners are provisioned from if you manage them as immutable images.

4. Turn on auto-update, or build re-provisioning into your pipeline. Self-hosted runners auto-update by default unless it was explicitly disabled (--disableupdate at config time). If your team disabled it โ€” often done to pin a known-good version for reproducibility โ€” that decision is exactly what put you at risk here. Either re-enable auto-update, or add a scheduled job that rebuilds/redeploys your runner image on a cadence shorter than 30 days.

5. Audit anywhere runners are provisioned from code. Terraform modules, Ansible playbooks, Packer images, Docker images referenced in actions-runner-controller (ARC) deployments on Kubernetes โ€” anywhere a version string or a base image tag is pinned, that pin is now a liability. Grep your infra-as-code for old runner version strings or stale base image digests before you assume "we upgraded" actually reached every runner.

Best practices

  • Don't wait for full enforcement to test. Deliberately watch a brownout window (the next job-execution-blocking one is September 9) with your current runner fleet and confirm nothing breaks, rather than finding out on September 25 in front of a production deploy.
  • Standardize on auto-update unless you have a specific, documented reason not to โ€” and if you do disable it, own the 30-day upgrade cadence explicitly rather than letting it drift.
  • Alert on brownout-window failures specifically. A CI failure that correlates with 11 AMโ€“3 PM ET on a brownout date is a strong, specific signal โ€” build a quick check for it rather than treating every flaky failure the same.
  • If you use ARC on Kubernetes, upgrading means rebuilding and rolling out a new runner image, not just editing a config value โ€” budget time for the image build/push/rollout, not just the version bump.

Common mistakes to avoid

  • Assuming "it worked last week" still holds. The schedule escalates weekly โ€” registration-only blocks in week one do not predict what happens once job-execution blocks start.
  • Checking only during business hours outside 11 AMโ€“3 PM ET. If your team's on-call rotation or deploy windows avoid that slot, you can genuinely miss every brownout until September 25 hits for real.
  • Pinning a specific runner version in infra-as-code "for stability" and forgetting to revisit it. A pin that was safe in March is exactly the kind of pin that fails silently here.
  • Fixing one runner and assuming the fleet is fixed. Ephemeral runners spun up from a container/VM image are only fixed once the image itself is rebuilt โ€” patching a running instance doesn't touch the image the next one boots from.

Troubleshooting

If a job suddenly fails with the runner appearing offline or unresponsive during a brownout window, check ./run.sh --version on the affected machine first before assuming a networking or capacity problem. If the version is below 2.329.0, or the last upgrade was more than 30 days ago, that's very likely your answer โ€” upgrade and re-run. If the version is current and the failure still correlates with a brownout date, it's worth filing with GitHub support, since that would indicate an enforcement bug rather than a genuine version gap.

FAQ

Does this affect GitHub-hosted runners (the standard ubuntu-latest, windows-latest, etc.)? No. This enforcement is specific to self-hosted runners you register and manage yourself. GitHub-hosted runners are unaffected.

Does this affect GitHub Enterprise Server (on-prem)? No, GitHub has explicitly stated GHES is not impacted at this time.

What if I already went through this for GitHub Enterprise Cloud with Data Residency? That edition hit full enforcement on July 31, 2026 already โ€” this article covers the separate, later timeline for standard github.com / GitHub Enterprise Cloud, running through September 25, 2026.

Is there any way to get an extension for my org? GitHub paused the original 2026 timeline once already due to readiness concerns, but as of the June 2026 changelog post the September 25 date is presented as final, with no per-org opt-out mechanism described. Don't plan around another pause.

What's the actual risk if I do nothing? Between now and September 25, intermittent CI failures during the ET brownout windows, worsening each week. After September 25, any runner still below the minimum version simply stops registering and stops executing jobs โ€” permanently, until upgraded.

Key takeaways

FactDetail
Enforcement startsBrownouts since Aug 24, 2026; full enforcement Sep 25, 2026
Minimum versionv2.329.0+ to register; latest release within 30 days to keep running jobs
Brownout window11:00 AMโ€“3:00 PM ET on scheduled dates
Not affectedGitHub-hosted runners, GitHub Enterprise Server
FixUpgrade runner binary/image; enable auto-update or re-provision within 30 days
Check version./run.sh --version or ./config.sh --version

Further Reading