Diagnosing Stuck GitLab CI/CD Pipelines: Runner and Executor Checks
When GitLab CI/CD jobs stay pending or running without logs, the Runner registration or executor is usually the problem. Use these ordered checks to isolate the fault and restore pipeline throughput.
01 Jan 2026, 16:03 UTC

The condition: pipelines that never leave pending or running
A GitLab CI/CD job that stays in pending or running indefinitely, with no logs appearing in the web UI, is almost always a Runner-side problem. The GitLab server has queued the job, but no Runner has picked it up, or the Runner started it and cannot create the execution environment. The useful takeaway is to check Runner registration and executor health before touching pipeline syntax or GitLab instance settings.
Common causes and quick diagnostics
| Symptom | Likely cause | Where to look |
|---|---|---|
Job stays pending, no Runner shown in UI | Runner not registered or offline | gitlab-runner list, GitLab UI Runners page |
Job shows running but no logs | Executor cannot start the job environment | Runner logs, executor configuration |
| Stuck after cache or artifact download | Network or DNS failure between Runner and GitLab | curl from the Runner host |
| Authentication or token errors in logs | Registration token expired or revoked | Runner logs, GitLab admin settings |
| Multiple jobs pile up behind one | Concurrency limit or host resource exhaustion | concurrent setting in config.toml |
Ordered checks and fixes
1. Confirm the Runner is registered and reachable
On the machine hosting the Runner, run:
sudo gitlab-runner list
This command requires sudo or membership in the gitlab-runner group. Expected check: the output lists each registered Runner with its URL, executor, and tags. If the list is empty or the Runner is missing, the instance cannot receive jobs.
Fix: Re-register the Runner using a current registration token from your GitLab project, group, or instance settings under CI/CD > Runners. Replace the placeholders below:
sudo gitlab-runner register \
--non-interactive \
--url "" \
--registration-token "" \
--executor "" \
--description ""
Risk: The registration token is sensitive. Do not paste it into tickets or chat channels. Rollback: If you unregister a Runner by mistake, jobs stop being picked up; re-register with the same token to restore service.
2. Check Runner configuration and executor
Open the Runner configuration file, typically /etc/gitlab-runner/config.toml, on the Runner host. Look for the executor value and the global concurrent limit. An executor is the mechanism the Runner uses to run jobs, such as shell, docker, or kubernetes.
Example configuration excerpt:
concurrent = 4
[[runners]]
url = "https://gitlab.example.com"
token = ""
executor = "docker"
[runners.docker]
image = "alpine:latest"
Fix: If the executor is wrong or its backend is unavailable, correct the executor value and any backend-specific settings, then restart the service:
sudo systemctl restart gitlab-runner
Risk: Changing the executor can require new container images, volume mounts, or Kubernetes pod specifications. Test in a staging environment before modifying a production Runner. Rollback: Back up config.toml before editing. To revert, restore the backup and restart the service.
3. Test network connectivity from the Runner host
Run the following on the Runner host, replacing the URL with your GitLab instance address:
curl -I
Expected check: an HTTP response header is returned. A timeout, DNS resolution failure, or connection refused indicates a firewall, proxy, or routing problem that prevents the Runner from polling for jobs or uploading logs.
Fix: Correct DNS records, firewall rules, or proxy environment variables so the Runner can reach the GitLab URL over HTTPS.
4. Inspect Runner logs for executor or authentication errors
On a systemd-based Runner host, view recent logs with:
sudo journalctl -u gitlab-runner -n 100 --no-pager
If the Runner logs to a file instead, use:
sudo tail -n 100 /var/log/gitlab-runner/log
Look for messages indicating connection failures, authentication rejection, or executor-specific errors such as Docker daemon unavailability or Kubernetes pod scheduling failures.
Fix: If the logs show token rejection, generate a new registration token in the GitLab UI and re-register the Runner. If the logs show executor errors, repair the underlying backend (for example, start the Docker daemon or fix Kubernetes credentials) and restart the Runner.
5. Verify with a minimal test pipeline
Create or update .gitlab-ci.yml in a test project:
test_runner:
script:
- echo hello
Push the change and watch the job in the GitLab UI. Expected check: the job transitions from pending to running to success, and logs appear. If this succeeds, the original stuck pipeline was likely job-specific, such as a missing tag, insufficient host resources, or a dependency that never resolves.
Practical verification and limitations
Run sudo gitlab-runner verify on the Runner host to confirm it can communicate with GitLab. In the GitLab UI, open CI/CD > Runners and look for a green status indicator next to the Runner. A green circle means GitLab received a recent heartbeat.
Limitations: This guide applies to self-managed GitLab instances with locally installed Runners. GitLab.com SaaS projects use GitLab-managed Runners; you cannot register your own instance Runners there. Executor behavior and configuration keys can vary between Runner versions. Recent Runner releases (16.x and later) use the commands shown here, but confirm against the documentation for your installed version.
When to escalate
Escalate to a GitLab administrator or support when:
- All checks above pass but pipelines remain stuck.
- Runner logs show internal errors that are not clearly tied to network, tokens, or executor backends.
- Multiple Runners across different projects are affected, which suggests an instance-wide problem rather than a single Runner fault.
- The GitLab instance itself shows degraded performance or unavailable CI/CD features.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.