GitLab cross-project pipeline trigger failed - invalid trigger token
Downstream pipeline does not start when the trigger API is called
Focused incident mode — strips away everything but this runbook.
Symptoms
- Downstream pipeline does not start when the trigger API is called
- HTTP 401 or 403 from the GitLab trigger API
- Parent pipeline shows 'Trigger failed' in the downstream job logs
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
Trigger token configuration
glab api /projects/<PROJECT_ID>/triggers --jq '.[] | {token, description, active}'Pipeline trigger API call
grep -B2 -A5 'curl.*trigger' .gitlab-ci.yml | head -15
Diagnostic flow
Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.
Guided decision tree is ready.
Steps with commands, expected output, and pass/fail branches.
Ranked root causes
Evidence checklist
- glab api /projects/<PROJECT_ID>/triggers shows the token as inactive
- Token was rotated or deleted by a project maintainer
Confirm before fixing
glab api /projects/<PROJECT_ID>/triggers --jq '.[] | {active, token_last_used}'Check token status
Fix
glab api -X POST /projects/<PROJECT_ID>/triggers -f description='new-trigger' -f active=trueCreate a new trigger token
Resolution runbook
Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.
curl -s -X POST -F token=<TRIGGER_TOKEN> -F ref=<BRANCH> https://gitlab.com/api/v4/projects/<PROJECT_ID>/trigger/pipeline | head -20Test the trigger API directly
glab api /projects/<PROJECT_ID>/triggers --jq '.[] | {active, token_last_used}'Check token status
glab api -X POST /projects/<PROJECT_ID>/triggers -f description='replacement-trigger' -f active=trueCreate a new trigger if the old one is invalid
Prevention
- Use project access tokens or CI/CD job tokens instead of trigger tokens when possible.
- Monitor trigger token usage via the GitLab audit log.
- Set trigger tokens as protected CI/CD variables rather than hardcoding them.
- Document cross-project pipeline dependencies and their trigger tokens.
Related runbooks
Same stack, same failure family — worth a skim.
docker push to registry.gitlab.com fails with 'unauthorized' or 401
Job stuck in 'pending' state with 'Waiting for a runner'
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.