highIntermediateSymptom-first#docker#image#registry#pull

GitLab CI image pull failed - private registry or missing image

Job fails with 'Error response from daemon: manifest for <image> not found'

Likely source:availabilityconfiguration

Focused incident mode — strips away everything but this runbook.

Symptoms

  • Job fails with 'Error response from daemon: manifest for <image> not found'
  • GitLab CI job log shows 'pulling image failed' or 'unauthorized'
  • Job stays in pending with 'Preparing environment' then fails on image pull

Evidence to grab

Collect these artifacts before you change anything — they prove (or rule out) each cause.

  • Image specified in .gitlab-ci.yml

    grep -E '^\s*image:' .gitlab-ci.yml | head -5
  • Docker registry credentials in GitLab

    glab api /projects/<PROJECT_ID>/variables --jq '.[] | select(.key | test("REGISTRY|DOCKER")) | .key'

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

  • Job fails with 'unauthorized: authentication required'
  • Image is in a private registry (e.g., ghcr.io, registry.gitlab.com)
  • No CI/CD variable named REGISTRY_PASSWORD or DOCKER_AUTH_CONFIG

Confirm before fixing

glab api /projects/<PROJECT_ID>/variables --jq '.[] | .key'
READ

List all CI/CD variables

Fix

glab api -X POST /projects/<PROJECT_ID>/variables -f key=REGISTRY_PASSWORD -f value=<TOKEN> -f protected=true -f masked=true
CHANGE

Add registry password as a protected CI variable

Resolution runbook

Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.

1
glab ci trace <PIPELINE_ID> --job <JOB_ID> | grep -E 'pulling|manifest|unauthorized' | head -10
READ

Read the image pull error

2
docker manifest inspect <IMAGE>:<TAG>
READ

Verify the image exists

3
glab api /projects/<PROJECT_ID>/variables --jq '.[] | .key'
READ

Check for registry credentials

4
glab api -X POST /projects/<PROJECT_ID>/variables -f key=REGISTRY_PASSWORD -f value=<TOKEN> -f masked=true
CHANGE

Add missing registry credentials

Prevention

  • Always pin images to a specific tag or SHA, never use :latest.
  • Store registry credentials as protected, masked CI/CD variables.
  • Pre-pull images on shared runners during off-peak hours.
  • Use GitLab's built-in Container Registry for first-party images.

Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.