GitLab Runner upgrades and version alignment

Runners must stay in step with the GitLab major and minor version, and older fleets need planned work for the Docker Machine deprecation. This page explains the order, the checks and the effort drivers.

On this page

Why GitLab Runner upgrades need their own plan

GitLab Runner should keep the same major.minor version as your GitLab instance, because features may not work properly across a version difference. If you are upgrading a self-managed GitLab server, the runners that execute its CI/CD jobs are part of the same change, and they often sit on a different version because they are updated on their own schedule. This section covers the runner side of that upgrade. It does not cover the full server upgrade, which has its own required stops and database prerequisites.

GitLab upgrades pass through required upgrade stops at x.2, x.5, x.8 and x.11, so a multi-version jump is planned as a sequence of hops. Runner versions should follow the server step: at each stop, move the server to that version and bring the runner fleet to the matching major.minor before the next hop. Confirm the exact path for your starting version in the GitLab upgrade paths documentation, since the stops and the versions between them depend on where you begin.

Do not defer the fleet review. The Docker Machine executor is deprecated as of GitLab 17.5 and scheduled for removal in GitLab 20.0, so older autoscaling fleets built on it need a replacement plan well before that release. Inventory every runner, its version, its executor and whether it uses Docker Machine, then decide which runners move to the GitLab Runner Autoscaler on your cloud provider. Ask your team to confirm which executors are in use before you set the upgrade sequence.

What changes for runners when GitLab moves to a new minor version

This table compares four changes that affect GitLab Runner fleets as the GitLab server moves to a new minor version, along with the impact on each runner and the action to take. Read each row against your current runner versions and executors before scheduling the server upgrade. The main takeaway is that runners must track the server's major.minor version, and older executor choices carry a removal date that falls within a known release line.

ChangeImpact on runnersAction needed
Major.minor alignment ruleGitLab advises keeping the Runner major.minor version in sync with the GitLab server, because features may not work properly across a version difference.Record the Runner and GitLab versions for every runner fleet, then plan runner upgrades to match each server minor version step.
Docker Machine executor deprecated in GitLab 17.5Runners using the Docker Machine executor are on a deprecated path and cannot be relied on as the platform moves forward.Inventory every runner using Docker Machine and plan a move to a supported autoscaling approach before the upgrade window.
Docker Machine removal scheduled for GitLab 20.0The Docker Machine executor is scheduled for removal in GitLab 20.0, so fleets still using it will need changes before that release.Confirm the removal details in the current runner documentation for your target version and set a migration deadline ahead of GitLab 20.0.
GitLab Runner Autoscaler recommended for AWS EC2, Azure or GCEThe documentation recommends the Runner Autoscaler as the replacement for Docker Machine on these clouds, which changes how VMs are provisioned and scaled.Test autoscaler configuration in a non-production runner group and confirm supported cloud and version requirements with the current docs.
Required upgrade stops at x.2, x.5, x.8 and x.11The GitLab server must pass through these stops, so runner alignment must be planned at each stop rather than only at the final target version.Map the server's upgrade path, then schedule a matching runner upgrade at each required stop the server crosses.
Registration token and registration workflow changesChanges to how runners register with the server can affect new runner builds and fleet automation scripts after an upgrade.Confirm the registration token and workflow details against the current runner documentation for the target version before changing automation.

How the major.minor alignment rule applies to your fleet

The rule asks for one thing: the GitLab Runner major.minor version should match the GitLab major.minor version it serves. If the server is on 19.5, the runners should be on 19.5 as well. GitLab advises this pairing because features may not work properly when the two versions differ, and a runner that lags behind can fail in ways that look like pipeline problems rather than version problems. The practical consequence is that a runner fleet is a dependency of your GitLab upgrade, not an afterthought to it. Each runner is only as current as the GitLab release it was last aligned with.

The rule governs the pairing during and after each upgrade step, not only at the end of a project. If your instance is several versions behind, the runners have to move along the same required upgrade stops as the server, such as x.2, x.5, x.8 and x.11, so that each stop is matched by a runner at the same major.minor. Plan the runner moves as explicit steps in the upgrade runbook, with a record of the runner version at every stop. Also check whether your pipelines pin a runner image or helper image, since those can drift from the registered runner version and change behavior independently.

Confirm with the GitLab Runner documentation whether patch-level differences are acceptable in your environment. The major.minor guidance is clear, but the supplied guidance does not address how much patch-level variance is tolerated, so do not assume that a runner one patch release behind is safe. Ask your team to pin runner versions in configuration management, record them in the change record for each upgrade, and decide in advance whether a patch-level mismatch is accepted or treated as a blocker.

Which runner fleets need attention first

Most self-managed GitLab instances run runners in more than one shape, and each shape ages differently. The fleet type decides which version check comes first, which executor is on a deprecation path, and which upgrade step must happen before the GitLab server moves.

Runners deployed with the GitLab chart

Runners installed through the GitLab Helm chart on Kubernetes are usually tied to the chart version that deployed them. The GitLab Runner image tag can drift from the GitLab server version if the chart values pin it separately. Check the runner image tag and the chart-to-GitLab version mapping before you change the server. For chart upgrades, the documented sequence is to upgrade runners first, so confirm that your pipeline can run the new runner image before the server moves. Write down which values file sets the tag so the change is reviewed.

Docker Machine executor on VMs

Runners on VMs that use the Docker Machine executor carry the most time-sensitive risk in this topic. The executor is deprecated as of GitLab 17.5 and is scheduled for removal in GitLab 20.0. Confirm which executor each runner's config.toml declares and whether machines are still provisioned through Docker Machine. Plan the move to the GitLab Runner Autoscaler before the 20.0 release, and test it on a non-production runner first so the replacement does not depend on the old executor.

Autoscaler on AWS, Azure or GCE

Runners that already use the GitLab Runner Autoscaler on AWS EC2, Azure or GCE are on the recommended path for cloud VM fleets. The main check is version alignment, since the Runner binary on the manager host and the autoscaling settings must match the GitLab minor version you are moving to. Confirm the image or instance template used for worker VMs includes a compatible Docker engine and that credentials and instance profiles still work after a Runner upgrade. Record the Runner version and the cloud provider settings together so the next upgrade starts from a known state.

Shell and Docker runners on long-lived hosts

Shell and Docker runners registered by hand on long-lived hosts are where manual version drift usually builds up. Packages get updated on the host while the Runner stays on an older release, or the Runner is upgraded without checking the GitLab minor version. Inventory every host, record the installed Runner version and the registration token type each runner uses, and list which hosts run the Runner as a service. Align each host to the GitLab major.minor version in the same change window as the server, and retire runners that no project uses.

Upgrade order by how GitLab was installed

With a cloud native deployment, the chart release sets the GitLab server version, so the runner fleet has to be ready before the server changes. Upgrade the runners to the target major.minor first, then run the chart upgrade. Runners that already match the target can keep executing jobs while the server moves, which keeps the pair aligned for as much of the change as possible.

  • Map the chart to a GitLab version: Confirm which GitLab version the target chart release deploys, and record it next to the runner version you plan to install.
  • Upgrade the runner release first: Move the GitLab Runner Helm release or image tag to the target major.minor, then confirm that test jobs start and finish.
  • Pin the runner image tag: Set the tag explicitly in your values file so a chart default cannot change the runner version during the server upgrade.
  • Hold the server rollout: Wait until runner pods report the target version and pick up jobs before you let the server deployment proceed.
  • Plan each intermediate stop: If your path crosses several required upgrade stops, repeat the runner alignment at each stop.

Before you close the change, check that runner pods, server pods and the chart release all report the same major.minor version.

What to inventory before changing any runner

Runner upgrades go wrong when the team does not know what is registered, how it was registered and which pipelines depend on it. Collect the items below before changing any version, because each one decides the upgrade order, the test scope and the rollback plan.

Every runner, its version and host

List each runner with its installed version, executor type, host or cluster, and the GitLab instance or group it serves. Include runners that appear idle, because stale runners often still hold tags that pipelines use. Compare each version with the GitLab major.minor you plan to run, since the GitLab Runner guidance is to keep the major and minor versions in sync with GitLab. Record the version gap for every runner so the upgrade order is clear.

Registration method and tokens in use

Record how each runner was registered, whether through a runner authentication token created in the GitLab UI or through an older registration token, and where the token is stored. Identify which scope each runner serves: instance, group or project. Registration behavior has changed across GitLab versions, so confirm current token behavior for your target version in the GitLab Runner documentation before you re-register anything.

Jobs and tags that need specific executors

Export the .gitlab-ci.yml files and project settings that reference runner tags, then map each tag to the runner that serves it. Note jobs that need Docker-in-Docker, privileged containers, GPU access or particular images. A runner upgrade that changes an executor or removes a tag can stop a job without any error in the pipeline definition, so this map is the basis for your test list.

Docker Machine settings on older fleets

For any runner using the Docker Machine executor, capture the autoscaling configuration: machine driver, idle count, idle time, maximum builds, and the cloud credentials used to create machines. The Docker Machine executor is deprecated as of GitLab 17.5 and scheduled for removal in GitLab 20.0, so these settings must be mapped to a supported autoscaling approach. Ask which replacement fits your cloud, since the Runner Autoscaler is recommended for AWS EC2, Azure and GCE.

A staging GitLab instance for runner tests

Prepare a test project or staging GitLab instance at the target version, with a runner registered to it and a copy of the representative pipelines. Include jobs that use the executors and tags from your inventory, plus one autoscaling job if you run that pattern. Test results from this environment decide whether a production runner can move, so the staging runner should match the production executor type and image sources as closely as possible.

Runner configuration file backups

Back up the runner configuration files, primarily config.toml, on every host before any change, along with service unit files and any certificates or credential helpers the runner references. Store copies outside the runner host, and record the checksum or revision. These files hold runner tokens and executor settings, so restrict access to the backup and confirm that a restore has been tested on a staging host.

Upgrading runners in the right order

This sequence keeps every GitLab Runner at the same major.minor version as the server, proves the new version on one canary runner before the fleet moves, and leaves a rollback path at each stage. It applies whether runners are installed as packages, containers or in a Kubernetes cluster.

  1. Confirm the target GitLab required stop

    Decide the GitLab version you are moving to and check the upgrade path documentation for any required upgrade stops between your current version and the target. Runner alignment follows the server version you actually land on, so the runner target is the major.minor of the final GitLab release in this upgrade, not the version you started from. Your check is a written upgrade plan naming each stop and the matching runner version for each stop.

  2. Record current runner versions

    Inventory every runner with its version, executor type, install method, host or cluster, and the tags and projects it serves. Use the runner version output on each host or the registered runner list in the GitLab Admin area, then compare each value with the current GitLab version. Your check is a single inventory that flags every runner whose major.minor differs from the server, so you know which ones are already out of step before any change is made.

  3. Back up runner configuration

    Copy the runner configuration file, typically config.toml, along with any executor settings, certificates, environment files and Helm values used for runners in cluster deployments. Store the copies in version control or a restricted backup location, because these files hold runner authentication tokens and should be protected like secrets. Record the currently installed package version or image tag so you can reinstall it. Your check is a restorable copy of each runner's configuration that you have tested by reading it back.

  4. Plan the Docker Machine fleet migration

    If any runner uses the Docker Machine executor, plan its move to the GitLab Runner Autoscaler before the upgrade reaches the release that removes Docker Machine. The Docker Machine executor is deprecated as of GitLab 17.5 and scheduled for removal in GitLab 20.0, and the autoscale documentation recommends the Runner Autoscaler for AWS EC2, Azure or GCE. Confirm the target cloud, instance images and access model with your platform team before changing runners. Your check is a written migration plan with a named owner and a parallel runner pool that can take jobs during cutover.

  5. Upgrade one canary runner

    Choose a non-critical runner that serves a small set of projects with tags matching real work, and upgrade it to the runner version that matches the target GitLab major.minor. Keep the previous package, image or Helm release revision available so you can roll back in minutes. Your check is that the runner reports the matching version, shows as online in the GitLab Admin area, and the service starts without configuration errors in its logs.

  6. Run representative jobs on the canary

    Run a set of pipelines that match your real workloads through the canary: a build with artifacts, a job that uses services or a container image pull, a job that reads CI/CD variables and a deployment job that reaches your target environments. Include the executor type you actually use and any custom certificates or proxies. Your check is a documented result for each job type, with logs reviewed for warnings about version mismatch or unsupported options. Any failure is a stop point, and you roll the canary back to its recorded version.

  7. Upgrade remaining runners and the server

    Once the canary passes, upgrade the remaining runners in small groups, keeping at least one runner per tag available, and then complete the GitLab server upgrade in the order your install method requires. For cloud native Helm deployments, upgrade runners first as the chart procedure expects, and for Linux package or other installs, follow the documented server steps. Your check is that every runner reports the target major.minor, all pipelines queue and run, and the server reports the expected version with no failed background migrations. Keep previous runner packages or chart revisions until the upgrade is accepted.

What makes runner upgrades take longer

This table lists the factors that expand a GitLab Runner upgrade and explains why each one adds work. Read each row as a question to answer about your fleet before you schedule the change. The main takeaway is that fleet size matters less than executor mix, pinned dependencies and network reach.

DriverWhy it adds workHow to reduce it
Number of runners and executor typesEach runner must match the GitLab major.minor version, and each executor type has its own configuration and test path.Inventory every runner, its executor and its host. Group runners by executor so one test plan covers each group.
Docker Machine fleets needing migrationThe Docker Machine executor is deprecated as of GitLab 17.5 and scheduled for removal in GitLab 20.0, so these runners need a replacement before the server moves past that point.Confirm the target platform first, then plan the GitLab Runner Autoscaler on AWS EC2, Azure or GCE as the documented replacement. Schedule this work ahead of the 20.0 release.
Custom executor scripts or imagesCustom scripts depend on the Runner's build and cleanup behavior, so a version change can break job setup or teardown in ways a standard job would not show.Keep scripts in version control, test them against the target Runner version in a staging project, and record which Runner version each script was written for.
Pinned CI images that depend on old runner behaviorImages or job definitions pinned to older behavior may assume older helper images, variable handling or cache paths that changed in a newer Runner.Search pipelines for pinned image tags and helper references. Run representative pipelines on a test runner before rolling out the upgrade.
Projects relying on specific tagsJobs that select runners by tag must still find a matching runner after the upgrade, and a renamed or removed tag can leave jobs queued with no runner to pick them up.Export the tag list per project and per group, keep tag names stable during the upgrade, and confirm each tag has at least one upgraded runner before retiring the old one.
Restricted or offline networks where packages must be stagedRunner packages and helper images must be copied into the network before installation, and each staged artifact adds a transfer and verification step.Mirror the Runner packages and images that match the target GitLab version into your internal registry or repository, and record the checksums of each artifact before the change window.

How to test a mixed-version fleet and roll back safely

Verify every runner after each step, before moving on. Confirm that the runner registers with the GitLab server and reports the version you expect, since the major.minor version should match the GitLab stop the server is on. Then run a canary pipeline that targets each executor type in the fleet: shell, Docker and any autoscaling executor. Check that artifacts upload and download correctly, that caches are restored from the expected location, and that service containers such as databases start and accept connections. Finally, confirm that jobs carrying each runner tag land on the runner you intended, because a tag that falls through to an old or unexpected runner can hide a version gap until a production pipeline fails.

Roll back by returning the runner to its previous package or image, not by changing the server. While the server stays on the matching required stop, a runner can be downgraded to the version it ran before the step, provided the server still supports it. This works only because the backup of the runner configuration and the inventory of runner versions, hosts, executors and tags you recorded in earlier steps are current. Keep the previous package or image available until the canary pipelines have passed for a full working cycle, and record which runners were moved back so the fleet inventory stays accurate.

Confirm the rollback procedure for your install method before you need it. The steps differ depending on whether runners were installed from packages, run as containers, or deployed through the Helm chart, and the GitLab Runner documentation is the source to check for your method. Test the downgrade on one non-production runner first, and ask your team to confirm how autoscaling runners handle jobs in flight during a rollback. A rehearsed rollback is the only evidence that the procedure will work under pressure.

Questions teams ask before upgrading GitLab Runner

What does a GitLab Runner upgrade cost?

The cost is the engineering time to inventory the fleet, plan the order of changes, upgrade each runner, test representative pipelines and document the result. Cost rises with the number of runners, the mix of executors, and how much of the fleet still runs Docker Machine, which needs a migration rather than a version bump. Routine upgrades of a small fleet on a supported executor are a bounded task, while migrating an autoscaling fleet adds build, networking and security work. The cost is largely one-time, with recurring effort only if you keep the fleet on a regular release cadence. Ask any partner for a written quote that separates inventory, executor migration, testing and handover, and states which runner versions and executors are in scope.

How long does a GitLab Runner upgrade take?

Duration depends mainly on how many runners you operate, which executors they use, and how much pipeline coverage exists to prove each runner still works. A fleet of a few runners on the shell or Docker executor with current GitLab versions can usually be upgraded in one planned change window. Autoscaling fleets, Kubernetes-hosted runners and Docker Machine replacements take longer because each needs its own validation. Thin test coverage adds time, because someone must design test jobs that exercise caches, artifacts, registry pulls and deployments. Request a schedule in the written scope that lists the runners, the environments to test and the change windows you will allow.

What does our team need to provide?

Your team needs to provide a current inventory of runners, including hostnames or cluster names, executor type, runner version, tags, and which projects or groups use each runner. You also need administrator access to the GitLab instance, access to the hosts or Kubernetes clusters that run the runners, and a non-production GitLab environment where runner changes can be tested. Agree on a change window with the teams that depend on the pipelines, and name an owner who can approve pipeline changes during testing. Confirm who holds the runner registration credentials and how they will be rotated, since these are needed for any re-registration.

Can our own team upgrade GitLab Runner without a partner?

Yes, for a small fleet that uses current GitLab versions and supported executors, an internal team can usually upgrade runners by following the runner documentation and matching the major and minor version to the GitLab server. The work gets harder with Docker Machine, where the executor is deprecated and must be replaced, and with runners deployed from a Helm chart, where the chart version, the GitLab version and the runner version must be kept consistent. Teams without recent experience with autoscaling or Kubernetes often underestimate the testing. A partner is most useful when the fleet is large, when the migration crosses several executors, or when the team lacks capacity for a parallel test environment.

Do you offer fixed-scope runner upgrade engagements?

Most DeployOpen engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts. For runner work, the written scope usually lists the runners and executors covered, the GitLab versions involved, the test cases that count as acceptance, the change windows, and the handover documents. Ongoing support and upgrades after the first change are available as retainers if your fleet needs regular alignment with each GitLab release. Ask for the scope to state what is excluded, such as changes to GitLab itself, cloud account setup, or pipeline rewrites in application repositories.

Does the Docker Machine removal in GitLab 20.0 change the plan?

Yes. The Docker Machine executor is deprecated as of GitLab 17.5 and is scheduled for removal in GitLab 20.0, so any fleet still using it needs a replacement plan before that release. The GitLab Runner Autoscaler is the recommended path for AWS EC2, Azure and Google Compute Engine, which means the migration is an executor change, not only a version upgrade. Plan the migration early, because it affects machine images, credentials, network paths and cost controls. Confirm the target executor with your cloud platform team before scoping, and check the GitLab 20.0 release notes when they are published.

What goes wrong when runners and the GitLab server drift apart?

Runners and the GitLab server can drift when runner versions lag behind a GitLab upgrade. GitLab advises keeping the Runner major and minor version in sync with GitLab, because features may not work properly across a version difference. Symptoms can be subtle, such as jobs that fail only when a newer keyword or cache behavior is used, or pipelines that pass in testing and fail in production. In chart-driven deployments, upgrade runners before the server so that the job execution side is ready for the features the server will use. Check your runner versions against the server version before every GitLab upgrade and record the result in the change ticket.

How DeployOpen scopes and delivers a runner upgrade

DeployOpen plans, implements and hands over GitLab Runner upgrades inside your own infrastructure, starting from a written inventory of every runner and the GitLab version it must match. Engagements are fixed-scope, so the runner fleet, executors, target versions and handover deliverables are agreed in writing before work begins.

How we scope

  • Inventory every runner, its executor type, host platform and the GitLab instance it registers to.
  • Agree the target GitLab major.minor version and the matching Runner version in the written scope.
  • Identify any Docker Machine executor fleets and record the migration path they need before the upgrade.

How we build

  • Upgrade runners before the GitLab server in chart-based deployments, confirming the order against your chosen upgrade plan.
  • Test registration, job execution, cache and artifact handling on a staging runner fleet before production changes.
  • Replace registration token workflows on older fleets with the authentication method your GitLab version supports.

How we hand over

  • Deliver a runner inventory with versions, executors, tags and owners, plus the version alignment record.
  • Document the rollback steps for each runner host and the verification checks run after each change.
  • Provide a runbook covering version checks, planned upgrades and the removal steps for deprecated executors.

How we support

  • Ongoing support, upgrades and continuous testing are available as a retainer for the runner fleet.
  • Retainers can cover runner version checks ahead of each GitLab minor release in your environment.
  • Ask any partner to confirm the runner and server versions in scope before quoting ongoing support.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.