Home Technical Support GitLab CI/CD Basics: Simple Pipelines, Advanced Features, and Common Errors

GitLab CI/CD Basics: Simple Pipelines, Advanced Features, and Common Errors

Last updated on Sep 08, 2026

GitLab CI/CD Basics: Simple Pipelines, Advanced Features, and Common Errors

The Working With GitLab CI/CD and Advanced GitLab CI/CD exercises appear across 8 courses including Security Champion, DevSecOps Professional, DevSecOps Expert, and others. These exercises introduce YAML-based pipeline configuration, artifact management, and manual deployment gates. This article covers the most common failure modes learners hit and how to fix them quickly.


Table of Contents

  1. YAML Syntax and Stage Definitions
  2. Job Name Must Match Stage Name
  3. Artifacts: Saving and Sharing Job Output
  4. allow_failure and Non-Blocking Scan Jobs
  5. Manual Approval Gates with when: manual
  6. GitLab CI Startup Timing and 502 Errors
  7. 2-Hour Machine Timeout
  8. Common Questions

YAML Syntax and Stage Definitions

Indentation Errors Break the Pipeline

YAML uses whitespace for structure. A single extra or missing space will cause the entire pipeline to fail silently or with a parse error.

Common mistake: Using tabs instead of spaces, or mixing indentation levels.

Fix: Use 2-space indentation consistently. Use the CI Lint tool at CI/CD > Pipelines or CI/CD > Jobs > CI Lint to validate your .gitlab-ci.yml before committing.

Stage Names Are Case-Sensitive

The verification checks for exact stage names. If the exercise asks for stages build, test, integration, staging, prod, these must match exactly. Build or BUILD will fail verification.

stages:
  - build
  - test
  1 - integration
  - staging
  - prod

Fix: Copy stage names directly from the exercise instructions. Do not rename them.

Don't Rename .gitlab-ci.yml

The pipeline only triggers when the file is named exactly .gitlab-ci.yml. Renaming it to .gitlab-ci1.yml or gitlab-ci.yml will result in the pipeline never running.

Fix: Ensure the file path is /root/django-nv/.gitlab-ci.yml (with the leading dot).


Job Name Must Match Stage Name

Verification Expects Job Name = Stage Name

In the simple pipeline exercise, the task verification script checks that each job's key name matches its stage value. For example:

build:
  stage: build
  script:
    - echo "This is a build step"

If you name the job build-job but set stage: build, the verification will fail.

Fix: The job key name and stage value must be identical: build maps to stage: build, test maps to stage: test, etc.

exit 1 Will Fail the Job

The exercises use exit 1 to intentionally fail a job, demonstrating how CI/CD uses exit codes. A non-zero exit code turns the job red (failed). Exit code 0 is green (passed).

Key concept: CI/CD uses the last command's exit code by default. If your script has multiple commands, only the final one determines pass/fail.


Artifacts: Saving and Sharing Job Output

Artifact Path Must Exist

When you declare an artifact path, the file must be created by the job's script before the job ends. If the path doesn't exist, you'll get:

cannot access 'vulnerabilities.json': No such file or directory

Fix: Ensure the script creates the file before the artifacts section references it:

integration:
  stage: integration
  script:
    - echo "this is an output" > output.txt
  artifacts:
    paths: [output.txt]
    when: always

when: always Is Required for Failed Jobs

By default, artifacts are only saved when a job passes. If your job intentionally fails with exit 1, you need when: always to preserve the output:

artifacts:
  paths: [output.txt]
  when: always

Without when: always, a failed job's artifacts are discarded.

Artifacts Have a Default Expiration

Without expire_in, artifacts persist indefinitely, consuming runner disk space:

artifacts:
  paths: [vulnerabilities.json]
  expire_in: 1 week

allow_failure and Non-Blocking Scan Jobs

Security Scans Fail by Design

When you embed a security scanner like Safety or Bandit into the pipeline, it will often find vulnerabilities and return a non-zero exit code. This causes the job to turn red and block the entire pipeline.

Fix: Add allow_failure: true to the scanning job. The job will show an exclamation mark (!) instead of a red X, and the pipeline continues:

sast:
  stage: build
  script:
    - docker run --rm hysnsec/bandit -r /src
  allow_failure: true

This is appropriate for DevSecOps Maturity Levels 1-2, where false positives are common and security is being introduced gradually.


Manual Approval Gates with when: manual

Production Deployments Require Human Approval

The when: manual keyword pauses the pipeline at a specific job, requiring a human to click Play in the GitLab UI before proceeding:

deploy:
  stage: deploy
  script:
    - echo "This is a deploy step."
  when: manual

Common mistake: Forgetting when: manual causes the pipeline to auto-deploy to production, which is a security risk.


GitLab CI Startup Timing and 502 Errors

GitLab Takes 3-5 Minutes to Start

When you first click Start the Exercise, GitLab CE needs time to initialize. During startup:

  • 502 Bad Gateway means GitLab is still booting. Wait 2-3 minutes and refresh.
  • 404 Not Found after waiting means the machine has been recycled. Refresh the exercise page and click Start the Exercise again.

Fix: If you see 502, be patient. If you see 404 after 5+ minutes, the 2-hour timeout has hit — restart the exercise.

GitLab Login Credentials

  • Username: root
  • Password: pdso-training
  • URL pattern: https://gitlab-ce-<machine-id>.lab.practical-devsecops.training

2-Hour Machine Timeout

All lab machines have a 2-hour active session limit. Every machine — GitLab CE, GitLab Runner, and DevSecOps Box — resets independently. When the timeout hits:

  • GitLab returns 404
  • All committed code is lost
  • All pipeline configurations are wiped

Fix: Refresh the exercise page and click Start the Exercise again. There is no way to preserve progress. The DevSecOps Box is stateless and resets on any page refresh or tab close.


Common Questions

Question Answer
My pipeline isn't running after I commit. Check that the file is named exactly .gitlab-ci.yml (with the dot). Use CI Lint to validate syntax.
I see "Invalid yaml" in the pipeline. Check indentation. YAML requires consistent 2-space indentation. No tabs allowed.
My job shows red even though the commands ran. The last command returned a non-zero exit code. Check for exit 1 or a failing command. Add allow_failure: true if intended.
Artifacts aren't appearing after the job runs. The file path in artifacts: paths: must match exactly what the script creates. If the job fails, add when: always.
How do I validate my .gitlab-ci.yml before committing? Use CI Lint at CI/CD > Pipelines or CI/CD > Jobs > CI Lint in the GitLab UI.
The verification says "One or more stage/job is missing." Ensure every job's key name matches its stage value exactly (e.g., build: with stage: build).

Wrap-Up

GitLab CI/CD pipelines are the backbone of automated security testing in these exercises. Remember: YAML indentation matters, job names must match stage names, use artifacts with when: always to save output from failing jobs, add allow_failure: true for security scans that find vulnerabilities, and use when: manual for production deployment gates. Every machine resets after 2 hours — there is no way to save progress.

Reach out to support with your lab ID if you encounter errors not covered in this guide.