Creuto is now an OpenAI Select Partner Read More

Software Architecture & Technical

Self-hosted runner version 2.329.0 is enforced today

GitHub now enforces a minimum self-hosted runner version on Enterprise Cloud. Runners below 2.329.0 cannot register, and stale ones stop running jobs.

Self-hosted runner version 2.329.0 is enforced today

As of today, Tuesday 29 September 2026, the minimum self-hosted runner version is enforced on GitHub Enterprise Cloud. Runners below 2.329.0 can no longer register or re-register, and runners below the separate runtime minimum stop executing jobs even though they registered fine yesterday. The date moved from 25 September, which is the only reason anyone got four extra days.

The short version, from GitHub's changelog of 28 September:

  • New enforcement date: Tuesday 29 September 2026. The change shipped Monday 28 September; full enforcement begins today.
  • Previous date: 25 September 2026, announced in the June timeline.
  • Who is affected: GitHub Enterprise Cloud. GitHub Enterprise Server is explicitly not impacted. GitHub Enterprise Cloud with Data Residency was already enforced on 31 July 2026.
  • Registration minimum: 2.329.0, released 15 October 2025.
  • Runtime minimum: higher than the registration minimum, and it moves.

Why the self-hosted runner version rule has two numbers, not one

The single most common misreading of this change is that 2.329.0 is the bar. It is not. GitHub's June changelog sets out two separate requirements that both have to hold.

The first is registration: to run config.sh and have Actions accept the runner, it must be on 2.329.0 or later. That is the version at which the rearchitected Actions backend recognises a runner at all.

The second is currency: to keep executing jobs, a runner must install each new runner release within 30 days of publication. GitHub is explicit that a runner pinned to 2.329.0 that never updates again will not pick up jobs. Any release counts — major, minor or patch. And when a critical security update ships, Actions pauses job queuing to that runner until it is applied, without waiting out the 30 days.

So "we upgraded to 2.329.0" is not a finished migration. It is the entry ticket.

Auto-update is doing more work than you think

By default the runner application updates itself when a new version is available, and GitHub confirms that runners with auto-update enabled meet the 30-day requirement automatically — provided they can reach the update service. That proviso is where most quiet failures live. A runner on an egress-restricted subnet, or behind a proxy that was tightened after the runner was provisioned, will sit happily registered and silently fall out of currency.

Auto-update is off for anything registered with --disableupdate, and for Actions Runner Controller deployments running with disableUpdate=true. GitHub called this out directly in the March pause notice: those runners must be updated manually on a regular cadence. If your Kubernetes runner images are built once and pinned, that is you.

How do I check my runner versions across a fleet

You have three mechanisms, and they answer different questions.

MechanismAnswersLimit
GET /orgs/{org}/actions/runnersWhat is registered now, including a version field per runnerScoped per org or repo, so a large estate needs iteration
GET /orgs/{org}/actions/runners/deprecations/{version}The registration_deprecates_at and runtime_deprecates_at dates for a given versionTells you the deadline for a version, not which of your runners are on it
Audit log eventsWhich versions are actively registeringRecorded at registration time only, so it is not a complete inventory

The runner version deprecations endpoint is the new piece and the one worth wiring into something. It exists at organisation and repository scope, takes a version string, and returns runner_version plus the two deprecation timestamps. Pair it with the listing endpoint and you have a job that reports, for every registered runner, how many days it has left — which is a far more useful alert than a version number in a spreadsheet.

The audit log route is worth knowing when API coverage is awkward. Enterprise owners can query org.register_self_hosted_runner, repo.register_self_hosted_runner and enterprise.register_self_hosted_runner, each of which carries the runner version. GitHub's own caveat applies: these are registration events, so a long-lived runner that registered eighteen months ago and has been upgrading quietly ever since will show its version from eighteen months ago.

Ephemeral and container runners fail differently

This is the part that decides whether today is an annoyance or an outage.

A long-lived runner that is already registered and current keeps working. Enforcement bites it later, when it drifts past the runtime minimum.

An ephemeral runner does not get that grace. Registered with the --ephemeral flag, it de-registers after processing a single job, which means it registers afresh for the next one. A registration block therefore applies on the very next job, not eventually. If your autoscaling pool is built from an image carrying a runner below 2.329.0, the pool stops producing usable runners immediately and jobs queue with no obvious error at the workflow level.

Actions Runner Controller is the same story with an extra layer: the version is baked into the container image, so the fix is a rebuild and a rollout, not a command on a box. If the image was last built before October 2025 and disableUpdate is set, it will not self-correct.

The practical order today is: check ephemeral and ARC pools first, because they break now; check long-lived VMs second, because they break later. Teams we work with on Kubernetes implementation usually find the runner image is the only container in the estate nobody owns.

What to do if your runners have already stopped

Upgrade to a current runner release rather than to 2.329.0. Upgrading to the registration floor satisfies enforcement for about as long as it takes to notice, then puts you back in the same position when the runtime minimum next moves.

Then fix the reason it happened. In our experience the cause is almost never that nobody knew — GitHub announced this in December 2025, extended it in February, paused it in March and republished the timeline in June. The cause is that no system owned the answer to "what version is every runner on". That is a ten-line job against two REST endpoints, and it is the difference between a calendar item and an incident.

If build machines in your estate are long-lived enough for this to be a surprise, the runner version is unlikely to be the only thing drifting on them. It is worth treating the build fleet as infrastructure with a lifecycle rather than as pets, which is the thinking behind how we approach CI/CD implementation and the wider DevOps and cloud engineering work around it. GitHub has form for moving deadlines on estate-wide changes, and we covered a similar one when GitHub raised its SSH key requirements — the pattern is identical, and so is the fix.

The question to answer before the end of the day is not whether your runners are on 2.329.0. It is what will tell you, without anyone asking, the next time the floor moves.

Frequently asked questions

GitHub requires self-hosted runners to be on version 2.329.0 or later to configure or register with Actions. Separately, a runner must install each new runner release within 30 days of publication to keep executing jobs, so the effective minimum for running work moves forward over time.

GitHub Enterprise Cloud began full enforcement of self-hosted runner version requirements on 29 September 2026. A runner below 2.329.0 can no longer register or re-register, and a runner more than 30 days behind the latest release will no longer be queued workflow jobs.

Call GET /orgs/{org}/actions/runners, which returns a version field for each registered runner, then call GET /orgs/{org}/actions/runners/deprecations/{version} to get the registration and runtime deprecation dates for that version. Together they give you days remaining per runner.

No. GitHub's changelog states that this shift only affects GitHub Enterprise Cloud and that GitHub Enterprise Server is not impacted. GitHub Enterprise Cloud with Data Residency was a separate case and was already enforced from 31 July 2026.

Runners with auto-update enabled meet the 30-day currency requirement automatically, provided they can reach GitHub's update service. Runners registered with --disableupdate, including Actions Runner Controller deployments using disableUpdate=true, must be upgraded manually on a regular cadence.

An ephemeral runner de-registers after each job and registers again for the next one, so the registration block applies immediately rather than at some future drift point. A pool built from an image below 2.329.0 stops producing usable runners as soon as enforcement starts.

Written by

Akash Mohapatra

Akash Mohapatra

Co Founder & Director

29 Sep 2026

·

6 min read

Share

LET'S CONNECT

Connect with Creuto!

Ready to take the first step towards unlocking opportunities, realizing goals, and embracing innovation? We're here and eager to connect.

We don't just aim to fit in – we strive to stand out. Experience the perfect blend of innovation, excellence, and trust that makes us truly unforgettable. Discover the difference with Creuto.

© 2026 Creuto All Rights Reserved