Skip to content
ohsudo, Home
CI/CD

GitLab CI "This job is stuck": why no runner picks it up, and how to fix it

Fix GitLab CI "This job is stuck because you don't have any active runners": match the job's tags, enable shared runners, check runner status and protected branches.

Beginner5 min readApplies to GitLab.com · GitLab self-managed 16+ · GitLab Runner

by OhSudo ··

Part of a learning path:Git for everyday work

Your pipeline sits there, with the job pending, and a yellow message on the job’s page:

This job is stuck because you don't have any active runners that can run this job.

Or, with slightly different wording:

This job is stuck because you don't have any active runners online or available with any of these tags assigned to them: docker, production

GitLab itself doesn’t run jobs. It puts them in a queue, and runners ask for work. Each runner only takes jobs that fit its rules. So this means that no runner that’s online is allowed to take this job, and the job itself is probably fine. The message’s last part, when it lists tags, is often the answer.

  1. The jobtags: docker, production
  2. Queuewaits for a runner
  3. Runnersnone online with those tags(breaks here)
GitLab doesn't run jobs; it queues them, and runners take only the jobs that fit their rules. No online runner may take this one, often because of its tags.

TL;DR

build:
tags: [docker] # a runner must have ALL of these

Compare those tags with what your runners have, in Settings → CI/CD → Runners. Is the list empty? Then turn on instance runners on that page, or register your own.

1. Look at the runners

In your project, Settings → CI/CD → Runners. You’ll see three kinds:

  • Project runners, for this project.
  • Group runners, shared by a group.
  • Instance runners: for everybody on the instance, called shared runners in older versions.

Each has a status dot. Green means it has contacted GitLab recently. If there are none at all, or all are grey, that’s your answer.

2. Turn on instance runners

If you’re on GitLab.com, or your administrator offers them, check Enable instance runners for this project on that page.

On GitLab.com, new accounts may be asked to verify with a card or phone, to fight abuse, before those runners work. There’s also a monthly limit of compute minutes for the Free tier. If you’ve used it up, the job says so, with a message about your quota. See it under Settings → Usage quotas.

3. Tags: the most common cause

A job only runs on a runner that has all of its tags:

deploy:
stage: deploy
tags: [docker, production]
script: ./deploy.sh

A runner tagged only with docker won’t take this job. So:

  • Remove a tag from the job if you don’t need it, or from an example you copied. A job with an old project’s tags is a very common cause.
  • Add the tag to the runner, from its page in Settings → CI/CD → Runners, by pressing the pencil icon.

A job with no tags needs a runner that allows those. A runner may have Run untagged jobs turned off, and that’s another common reason. Turn it on, or add a tag to the job.

Variables work in tags too, so check what yours expand to:

tags: [$RUNNER_TAG]

4. Is the runner online and healthy?

On the machine with the runner:

Terminal window
sudo gitlab-runner status
sudo gitlab-runner verify
sudo gitlab-runner list
sudo journalctl -u gitlab-runner -n 30 --no-pager
Verifying runner... is valid runner=AbC123

is not valid or is removed means its token’s no longer accepted, so register it again:

Terminal window
sudo gitlab-runner register \
--url https://gitlab.com \
--token glrt-xxxxxxxxxxxxxxxxxxxx \
--executor docker \
--docker-image alpine:3.23

Take the token from New project runner on the Runners page. If the service is stopped, start it with sudo systemctl enable --now gitlab-runner. A runner on another network needs outbound HTTPS to your GitLab, as a runner connects out, with nothing connecting in. A wrong clock can break this too, since TLS certificates have dates.

5. A protected or paused runner

A protected runner only takes jobs on protected branches and tags. So a job from a feature branch stays stuck, while the same job on main runs. Turn off Protected on the runner if that’s not what you want, or protect the branch.

Other settings on the same page can do this:

  • Paused: the runner takes nothing.
  • Lock to current projects: it can’t be added to another project.
  • Group runners may be turned off for this project, under Enable group runners.

6. Busy, rather than stuck

If a job is only pending, with no “stuck” message, then a runner fits and it’s busy. Each runner takes a limited number of jobs, and the setting is at the top of /etc/gitlab-runner/config.toml:

concurrent = 4
[[runners]]
name = "docker-runner"
limit = 4

concurrent is the total for this machine, and the default is 1 when you install it. So one long job can hold everything up. Raise it if the machine can handle more. No restart is needed, as the runner reloads this file.

7. Can’t find a reason?

Self-managed GitLab has a few more things to look at, for administrators:

  • Under Admin → CI/CD → Runners, see if the runner’s there, and what its last contact was.
  • Sidekiq may be struggling, in which case jobs don’t move at all, even with healthy runners. Check under Admin → Monitoring → Background jobs.

Then test the most simple job, to take your own file out of the question:

hello:
script: echo hello

If it runs, add your settings back a step at a time. The CI/CD Pipeline Generator writes a working .gitlab-ci.yml for you, with no tags, so it runs on instance runners.

Warning

Take care with what you register a runner on. Anyone who can push to the project can run commands on that machine, so don’t use your laptop or a production server. And don’t use the shell executor, or a privileged Docker runner, for projects where strangers can open merge requests.

Shell, we have a problem!

Similar, but different: This job is creating too many jobs or a quota message means you’ve hit a limit, not a runner problem. Cannot connect to the Docker daemon is a job that’s running and needs Docker: see that article. A job that’s created and never pending is waiting for an earlier stage, or a needs. And on GitHub, the closest thing is Waiting for a runner to pick up this job.

Found this useful? Share it.

Found a mistake? Let us know at contact@ohsudo.com.

Tools

Try it yourself

Articles

Related articles