🎉 DevOps Interview Prep Bundle is live — 1000+ Q&A across 20 topicsGet it →
All Articles

GitLab Runner Offline: Fix in 5 Minutes

GitLab Runner showing as offline or stale even though the process is running? Here is exactly how to diagnose token issues, network connectivity, version mismatches, and concurrency exhaustion behind a stuck runner.

Shubham3 min read
Share:Tweet

A runner marked offline in GitLab's UI while the process on the machine looks fine is one of the more confusing states — the runner and GitLab disagree about connectivity, and the error rarely points at the real cause directly.

Step 1: Confirm the Runner Process Is Actually Healthy

bash
sudo gitlab-runner status
# gitlab-runner: pid, beat: 500ms
 
sudo gitlab-runner verify
# Verifying runner... is alive                       runner=AbCdEfGh

If verify succeeds but GitLab's UI still shows offline, the issue is in the heartbeat/registration path, not the runner process itself.

Cause 1: Runner Token Was Reset or Revoked

bash
sudo cat /etc/gitlab-runner/config.toml
# [[runners]]
#   token = "glrt-xxxxxxxxxxxx"

If someone regenerated the project/group runner registration token in GitLab (common during a security rotation), existing runners using the old token silently stop authenticating — no clear error, they just go offline.

bash
# Check the runner logs for auth failures
sudo journalctl -u gitlab-runner -n 100 --no-pager | grep -i "40[13]\|unauthorized\|forbidden"

Fix — re-register with the current token:

bash
sudo gitlab-runner unregister --name my-runner
sudo gitlab-runner register \
  --url https://gitlab.com/ \
  --registration-token NEW_TOKEN \
  --executor docker \
  --docker-image alpine:latest

Cause 2: Runner Can't Reach GitLab (Network/Firewall)

bash
# Test actual connectivity from the runner host
curl -v https://gitlab.com/api/v4/version

If this hangs or fails, the runner's heartbeat requests are failing silently — GitLab marks a runner offline after it misses heartbeats for a few minutes, with no error surfaced on the runner side beyond connection timeouts in the logs.

bash
sudo journalctl -u gitlab-runner -n 100 --no-pager | grep -i "timeout\|connection refused\|no route"

Fix — check firewall/proxy rules for outbound HTTPS to your GitLab instance:

bash
# If behind a corporate proxy, the runner needs it configured explicitly —
# it does not inherit shell environment proxy settings automatically
sudo systemctl edit gitlab-runner
ini
[Service]
Environment="HTTPS_PROXY=http://proxy.internal:8080"
Environment="NO_PROXY=localhost,127.0.0.1"
bash
sudo systemctl daemon-reload
sudo systemctl restart gitlab-runner

Cause 3: Clock Skew Between Runner Host and GitLab

bash
timedatectl status
# If "System clock synchronized: no" — this can cause heartbeat/token
# validation to fail intermittently

Fix — ensure NTP sync is active:

bash
sudo timedatectl set-ntp true
sudo systemctl restart systemd-timesyncd

Clock skew of more than a few minutes can cause token/JWT-based auth to fail in ways that look exactly like a connectivity problem.

Cause 4: Runner Version Too Old for the GitLab Server Version

bash
gitlab-runner --version
# Compare against your GitLab instance's version — GitLab officially
# supports runners within 2 minor versions, older ones can behave unpredictably

Fix — update the runner:

bash
# Debian/Ubuntu
sudo apt-get update && sudo apt-get install gitlab-runner
 
# Or via the official install script for a specific version
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt-get install gitlab-runner

Cause 5: concurrent Limit Exhausted, New Jobs Queue and Runner Appears Stuck

toml
# /etc/gitlab-runner/config.toml
concurrent = 4    # Only 4 jobs can run simultaneously across all configured runners

If all concurrent slots are occupied by long-running or hung jobs, new jobs queue indefinitely and the runner can appear unresponsive even though it's technically online.

bash
sudo gitlab-runner list    # Shows configured runners and their concurrency

Fix — increase concurrency if the host has capacity, and investigate why jobs are running long:

toml
concurrent = 8
bash
sudo systemctl restart gitlab-runner

Diagnostic Checklist

bash
sudo gitlab-runner status                                    # process health
sudo gitlab-runner verify                                     # token validity against GitLab
curl -v https://gitlab.com/api/v4/version                     # network path
timedatectl status                                             # clock sync
gitlab-runner --version                                        # version skew check
sudo journalctl -u gitlab-runner -n 100 --no-pager             # actual error detail

More CI/CD troubleshooting? Read our GitLab CI pipeline failing fix and GitHub Actions workflow not triggering fix.

🔧

Today I Fixed

Short real fixes from production — posted daily

Browse fixes
Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments