Originally published on docker.learnio.dev — part of the Docker fundamentals course. View this lesson on the original site.

Match the failing stage to the first command

Build, push, and pull failures look alike in chat logs but have different root causes. Name the stage first, then run the smallest command that confirms or rules out the usual suspect.

flowchart TD
  E[Error message] --> S{Which stage failed?}
  S -->|Build| B[Plain build output plus context checks]
  S -->|Push| P[Auth, repo name, quota]
  S -->|Pull or run| R[Tag, digest, platform]

Build failures

Get step-by-step output instead of a compact progress UI:

docker buildx build --progress=plain -t myorg/app:dev .

Common errors and first checks:

Error or symptom First commands
Cannot connect to the Docker daemon docker version
No space left on device docker system df
failed to compute cache key / file not found Confirm build context path, COPY sources, and .dockerignore
executor failed running command Read the failing RUN line; reproduce it with --progress=plain
network timeout during RUN Retry with plain output; check proxy and DNS from inside build

Inspect context size when transfers look wrong:

du -sh .
docker build --progress=plain .

Prune only after you know disk pressure is real:

docker system df
docker builder prune --filter until=24h

Push failures

Confirm login and permissions before rewriting the Dockerfile:

docker login ghcr.io
echo "$GITHUB_TOKEN" | docker login ghcr.io -u USERNAME --password-stdin
docker buildx ls

Typical push errors:

Error or symptom First commands
denied: requested access to the resource is denied Re-login; verify repo name, org permissions, and token scopes
name unknown / repository does not exist Check registry host, namespace, and repository spelling
manifest invalid Inspect local tag; rebuild with explicit --platform if needed
blob upload unknown / unexpected status Retry push; check registry status and quota

Push with plain exporter logging when CI hides details:

docker buildx build \
  --progress=plain \
  --tag ghcr.io/myorg/app:test \
  --push \
  .

Pull and run failures

Verify the reference exists and carries the platform you need:

docker buildx imagetools inspect ghcr.io/myorg/app:1.4.2
docker buildx imagetools inspect ghcr.io/myorg/app@sha256:abc123...
docker pull ghcr.io/myorg/app:1.4.2

Typical pull and start errors:

Error or symptom First commands
manifest unknown Confirm tag, registry host, and whether the image was pushed
no matching manifest for linux/arm64 docker buildx imagetools inspect for platform list
exec format error Compare host architecture with image platform
pull access denied docker login to the correct registry

After pull, run with the same entrypoint CI uses:

docker run --rm ghcr.io/myorg/app:1.4.2 --version
docker run --rm -p 8080:8080 ghcr.io/myorg/app:1.4.2

Keep the loop short

  1. Identify build vs push vs pull.
  2. Re-run the failing step with plain progress output.
  3. Inspect the registry reference with imagetools when tags or platforms are in doubt.
  4. Change one variable at a time: context, credentials, tag, or platform.

Destructive cleanup is a last resort, not a first response.

From Docker fundamentals — Images, layers, tags, and everyday commands