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
- Identify build vs push vs pull.
- Re-run the failing step with plain progress output.
- Inspect the registry reference with
imagetoolswhen tags or platforms are in doubt. - 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