GitLab Pipeline Troubleshooting

Every developer meets a red pipeline sooner or later. A calm, step-by-step approach finds the cause quickly. Most failures fall into a handful of patterns: a typo in the YAML file, a missing runner, a broken test, or a missing variable.

Think of a doctor visit. The doctor checks symptoms, narrows the cause, and prescribes a fix. Pipeline debugging follows the same path.

The Debugging Path

  Pipeline red?
       │
       ▼
  Did the pipeline even start?
       ├─ No  → Check YAML syntax and rules
       └─ Yes → Which job failed?
                    │
                    ▼
            Open the job log
                    │
        ┌───────────┼──────────────┐
        ▼           ▼              ▼
   Stuck pending  Script error   Environment error
   Check runners  Fix the code   Check image, variables, cache

Know the Job Statuses

StatusMeaning
CreatedThe job exists and waits for earlier stages
PendingThe job waits for a free runner
RunningA runner executes the commands
PassedEvery command succeeded
FailedA command returned an error code
CanceledSomeone stopped the job
SkippedA rule or an earlier failure prevented the job
ManualThe job waits for a person to press play

Problem 1: No Pipeline Appears

CauseFix
File name is wrongName the file exactly .gitlab-ci.yml in the repository root
YAML syntax errorValidate the file in the pipeline editor
Rules exclude every jobRead the rules and match them to your branch or event
Pipelines are disabledEnable CI/CD under Settings → General → Visibility

Open Build → Pipeline editor. The Validate tab reports syntax errors with line numbers.

Problem 2: A Job Stays Pending

  Job status: pending
  "This job is stuck because the project doesn't have any runners online
   assigned to it."

Check these items in order.

  1. Open Settings → CI/CD → Runners and confirm a runner shows a green dot.
  2. Compare the tags on the job with the tags on the runner. A job with a tag needs a runner that carries the same tag.
  3. Check whether the runner accepts jobs from protected branches only.
  4. Confirm the runner has free capacity. A busy runner queues new jobs.

Problem 3: A Script Fails

The log shows each command and the first error. Read upward from the final line.

  $ npm test
  FAIL tests/payment.test.js
    ● should validate card number
  npm ERR! Test failed.
  ERROR: Job failed: exit code 1

Reproduce the failure on your computer with the same image and commands. A local match proves the code is at fault. A local pass points to a difference in the environment.

Problem 4: Environment Differences

SymptomLikely CauseFix
command not foundTool missing from the imagePick an image that includes the tool or install it in the script
Cannot pull imageWrong image name or no registry accessCheck the spelling and add registry credentials
Variable is emptyVariable is protected and the branch is notRun on a protected branch or adjust the variable
Cannot find moduleStale or missing cacheClear runner caches and rerun
Permission denied on a scriptFile lacks execute permissionRun chmod +x script.sh and commit the change

Problem 5: Timeouts and Slow Jobs

A job that exceeds its time limit fails with a timeout message. Raise the limit for a heavy job or split the work into smaller jobs.

slow-tests:
  script:
    - npm run test:all
  timeout: 45 minutes

Problem 6: Flaky Failures

A flaky job passes on one run and fails on the next with the same code. Network hiccups cause many flaky failures. The retry keyword reruns a job automatically.

install:
  script:
    - npm ci
  retry:
    max: 2
    when:
      - runner_system_failure
      - stuck_or_timeout_failure

Retries mask real bugs when applied to test jobs. Use them for infrastructure issues.

Add Debug Output

Print values that help you see what the runner sees.

debug-info:
  script:
    - echo "Branch: $CI_COMMIT_BRANCH"
    - echo "Runner: $CI_RUNNER_DESCRIPTION"
    - pwd
    - ls -la

GitLab offers a debug trace through the variable CI_DEBUG_TRACE. The trace prints every variable value, including secrets, into the job log. Enable it only in a private project and delete the log after the test.

Useful Interface Tools

  • The Pipeline editor validates YAML and visualizes job relationships.
  • The Full configuration tab shows the merged result of includes and extends.
  • The Retry button reruns a failed job only.
  • The Clear runner caches button resets stale caches.
  • The job page shows the runner name, image, and duration.

Troubleshooting Checklist

  1. Read the last twenty lines of the failing job log.
  2. Confirm the same code passes on your computer.
  3. Compare image versions between local and pipeline runs.
  4. Verify variables, protected status, and branch.
  5. Clear the cache and retry once.
  6. Write down the cause and fix in your team wiki so that the next person solves it faster.