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
| Status | Meaning |
|---|---|
| Created | The job exists and waits for earlier stages |
| Pending | The job waits for a free runner |
| Running | A runner executes the commands |
| Passed | Every command succeeded |
| Failed | A command returned an error code |
| Canceled | Someone stopped the job |
| Skipped | A rule or an earlier failure prevented the job |
| Manual | The job waits for a person to press play |
Problem 1: No Pipeline Appears
| Cause | Fix |
|---|---|
| File name is wrong | Name the file exactly .gitlab-ci.yml in the repository root |
| YAML syntax error | Validate the file in the pipeline editor |
| Rules exclude every job | Read the rules and match them to your branch or event |
| Pipelines are disabled | Enable 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.
- Open Settings → CI/CD → Runners and confirm a runner shows a green dot.
- 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.
- Check whether the runner accepts jobs from protected branches only.
- 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
| Symptom | Likely Cause | Fix |
|---|---|---|
| command not found | Tool missing from the image | Pick an image that includes the tool or install it in the script |
| Cannot pull image | Wrong image name or no registry access | Check the spelling and add registry credentials |
| Variable is empty | Variable is protected and the branch is not | Run on a protected branch or adjust the variable |
| Cannot find module | Stale or missing cache | Clear runner caches and rerun |
| Permission denied on a script | File lacks execute permission | Run 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
- Read the last twenty lines of the failing job log.
- Confirm the same code passes on your computer.
- Compare image versions between local and pipeline runs.
- Verify variables, protected status, and branch.
- Clear the cache and retry once.
- Write down the cause and fix in your team wiki so that the next person solves it faster.
