This error means your GitLab CI job is stuck because no available runner is registered and configured to pick it up.

Here’s how to fix the "No Matching Runner Found" error in GitLab CI, covering all the common reasons this happens:

1. Runner Tags Mismatch

  • Diagnosis: Check the tags defined in your .gitlab-ci.yml file for the specific job. Then, go to your GitLab project’s Settings > CI/CD > Runners and examine the tags assigned to your registered runners.
  • Cause: The job’s tags must exactly match at least one of the runner’s tags. If there’s a typo, a missing tag, or an extra tag on either side, the runner won’t see the job as a match.
  • Fix:
    • If .gitlab-ci.yml is wrong: Correct the tags. For example, if your runner has docker and linux tags, your job might look like this:
      my_job:
        stage: build
        script:
          - echo "Building..."
        tags:
          - docker
          - linux
      
    • If runner tags are wrong: Go to the runner’s edit page in GitLab (Admin Area > CI/CD > Runners or Group/Project > Settings > CI/CD > Runners), find the runner, and edit its tags to match your job’s requirements.
  • Why it works: Tags are the primary way GitLab matches jobs to specific runners. It’s a direct key-value lookup.

2. Runner is Paused or Offline

  • Diagnosis: In your GitLab project’s Settings > CI/CD > Runners, look at the status icon next to your runners. A green circle means online and active, a gray circle means paused or disconnected.
  • Cause: The runner agent process might have crashed, the server it’s running on might be down, or the runner was manually paused.
  • Fix:
    • If paused: Click the "Resume" button next to the runner in the GitLab UI.
    • If offline: Log in to the server where the runner is installed and restart the GitLab Runner service. On Linux, this is typically: sudo gitlab-runner restart. On Docker, docker restart <runner_container_name>.
  • Why it works: A runner must be running and connected to GitLab to poll for and execute jobs. Restarting or resuming makes it available again.

3. Runner Scope Mismatch (Project vs. Group vs. Shared)

  • Diagnosis: Check the scope of the runner in GitLab (Admin Area > CI/CD > Runners for shared runners, or Settings > CI/CD > Runners for group/project runners). Then check where the job is defined in your .gitlab-ci.yml.
  • Cause:
    • Shared runners: Are enabled for the entire GitLab instance. They can run jobs for any project.
    • Group runners: Are available to all projects within a specific GitLab group.
    • Project runners: Are tied to a single project. If your job requires a specific scope (e.g., a project runner) but only a shared runner is available and active, it won’t match.
  • Fix:
    • Enable appropriate runners: Ensure the correct scope of runners is enabled. For project runners, go to Settings > CI/CD > Runners and ensure "Enable this runner for your projects" is checked. For group runners, configure them at the group level.
    • Register a new runner: If no runner of the correct scope and with the right tags exists, you may need to register a new one.
    • Adjust .gitlab-ci.yml: If you intended to use a broader scope runner, ensure your job doesn’t have overly restrictive tag requirements.
  • Why it works: GitLab uses runner scope to determine which projects can use a given runner. A job can only be picked up by a runner whose scope includes the project it belongs to.

4. Runner is Not Connected to the Correct GitLab Instance/URL

  • Diagnosis: On the server hosting the runner, check the runner’s configuration file (/etc/gitlab-runner/config.toml or ~/.gitlab-runner/config.toml). Look for the [[runners]] section and verify the url parameter.
  • Cause: The runner was registered with a different GitLab instance URL (e.g., https://gitlab.com vs. https://gitlab.yourcompany.com) or the URL has changed.
  • Fix: Edit the config.toml file on the runner’s server and update the url to the correct GitLab instance URL. After saving, restart the GitLab Runner service: sudo gitlab-runner restart.
  • Why it works: The runner agent periodically polls this URL to check for new jobs. An incorrect URL means it’s looking in the wrong place.

5. Runner Executor Configuration Issues

  • Diagnosis: Review the executor type in the runner’s config.toml (e.g., docker, shell, kubernetes). Check the specific configuration for that executor (e.g., [runners.docker] section for Docker).
  • Cause: For executors like Docker or Kubernetes, the runner needs access to a Docker daemon or a Kubernetes cluster, respectively. If the Docker daemon isn’t running, or the Kubernetes context is misconfigured, the runner might appear online but fail to pick up jobs that require its specific executor.
  • Fix:
    • Docker: Ensure the Docker daemon is running (sudo systemctl status docker). Check for any errors in Docker logs.
    • Kubernetes: Verify your kubeconfig file is correctly set up and the runner has permissions to create pods in the target namespace.
  • Why it works: The executor is the mechanism that actually runs the job’s script. If the underlying environment for the executor isn’t functional, the runner can’t spin up the necessary containers or environments to execute the job, even if it’s connected to GitLab.

6. Too Many Concurrent Jobs on the Runner

  • Diagnosis: In the runner’s config.toml, check the concurrent setting. Also, check the GitLab UI (Settings > CI/CD > Runners) for the "N jobs / M runners" status.
  • Cause: Each runner has a limit on how many jobs it can run simultaneously, defined by the concurrent parameter in its configuration. If all its concurrent slots are already occupied by other jobs, it cannot pick up new ones.
  • Fix:
    • Increase concurrent limit: Edit config.toml on the runner server and increase the concurrent value. For example, change concurrent = 2 to concurrent = 4. Then restart the runner: sudo gitlab-runner restart.
    • Register more runners: Add more runners with the appropriate tags.
    • Optimize .gitlab-ci.yml: Reduce parallel jobs in your pipeline if possible, or use needs to create a more sequential flow where appropriate.
  • Why it works: This setting directly limits the runner’s capacity. By increasing it or adding more runners, you increase the total available execution slots.

After addressing these points, your jobs should start picking up. The next error you’ll likely encounter is a Job Aborted or a specific script execution error if the runner is online but the job itself fails.

Want structured learning?

Take the full Gitlab-ci course →