← Debugging Guides

阅读中文版本

GitLab CI Job Stuck — No Runner Matches the Tags

Fix jobs stuck at "This job is stuck" by aligning runner tags, checking shared-runner availability, and removing unmatched tag requirements.

intermediatedebugginggitlab-cirunnersci

Symptoms

  • A pipeline job shows "This job is stuck because you don't have any active runners"
  • Jobs with a specific tag never start while untagged jobs do
  • Stuck jobs spend the whole timeout pending

Possible causes

  • The job tags do not match the tags on any registered runner
  • All matching runners are offline, paused, or at capacity
  • Shared runners are disabled for the project

Diagnosis steps

Compare job tags with runner tags

grep -n "tags:" .gitlab-ci.yml; gitlab-runner list

Interpretation

If no runner declares the job tag, the job can never be picked up.

Check runner availability in GitLab

Admin → Runners → filter by tag and status

Interpretation

Offline or paused runners explain a stuck job even when tags match.

Root cause

GitLab schedules a job only on a runner that advertises every tag the job requires. A tag with no matching runner leaves the job pending until timeout ("stuck"), because no runner is eligible.

Fix

Align tags between jobs and runners, register a runner with the needed tags, ensure matching runners are online and unpaused, and remove unnecessary tags from jobs.

Risk note

Using tags that only exist on ephemeral runners makes pipelines flaky when they scale down; document runner fleet requirements.

Verify the fix

Rerun the pipeline and confirm the job is picked up by a matching runner and completes; verify the runner shows the job in its recent builds.

Symptoms

This debugging guide addresses “GitLab CI Job Stuck — No Runner Matches the Tags”. Start from the symptoms, follow the ordered diagnostics, and confirm each hypothesis before moving on; the fix and verification steps then close the loop.

Observed symptoms include:

  • A pipeline job shows “This job is stuck because you don’t have any active runners”
  • Jobs with a specific tag never start while untagged jobs do
  • Stuck jobs spend the whole timeout pending

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Compare job tags with runner tags

grep -n "tags:" .gitlab-ci.yml; gitlab-runner list

If no runner declares the job tag, the job can never be picked up.

Step 2: Check runner availability in GitLab

Admin → Runners → filter by tag and status

Offline or paused runners explain a stuck job even when tags match.

Likely contributors, in order of frequency:

  • The job tags do not match the tags on any registered runner
  • All matching runners are offline, paused, or at capacity
  • Shared runners are disabled for the project

Root Cause

GitLab schedules a job only on a runner that advertises every tag the job requires. A tag with no matching runner leaves the job pending until timeout (“stuck”), because no runner is eligible.

The Fix

Align tags between jobs and runners, register a runner with the needed tags, ensure matching runners are online and unpaused, and remove unnecessary tags from jobs.

Watch out: Using tags that only exist on ephemeral runners makes pipelines flaky when they scale down; document runner fleet requirements.

stages: [build]

build:
  stage: build
  tags:
    - docker        # every eligible runner must advertise this tag
    - linux
  script:
    - make build

# check registered runners and their tags
# gitlab-runner list
# gitlab-runner verify

Verify and Prevent

Rerun the pipeline and confirm the job is picked up by a matching runner and completes; verify the runner shows the job in its recent builds.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.