Image Tags, Digests, Mutable vs Immutable References, Pull Policies, Pinning, and Reproducibility: Diagnostics, Failure Modes, Security, and Performance
Diagnose image-identity incidents without rebuilding away the evidence. This lesson separates stale local cache, moved tags, platform-index confusion, reused release names, bad pull-policy assumptions, and rebuild-during-promotion failures.
Learning objectives
- Preserve first-failure image/reference evidence before pulling, rebuilding, retagging, or recreating containers.
- Separate wrong context, stale local cache, moved registry tag, wrong platform descriptor, local image ID, and registry digest failures.
- Diagnose a tag-drift incident by comparing requested reference, local image ID, RepoDigests, and current registry resolution.
- Explain why broad cleanup, forced rebuilds, and tag overwrites destroy useful incident evidence.
- Recover by applying the smallest identity correction and then verifying exact digest behavior.
1. Failure model: “wrong image” has several causal layers
When two hosts run different behavior from the same tag, do not start by deleting images. First ask which context each client addressed, what local object each container uses, whether the hosts pulled at different times, what the registry tag resolves to now, and whether a multi-platform index selected different child manifests. Each answer belongs to a different state layer.
2. Evidence-first diagnostic sequence
-
Record host, architecture,
docker version, context, and current time. - Inspect the affected container: requested image string, local image ID, creation time, labels, and platform.
- Inspect the local image: ID, RepoTags, RepoDigests, OS/architecture, created/config metadata.
- Resolve the registry reference without overwriting evidence where possible.
- For multi-platform references, identify index and child manifest digests.
- Only then decide whether the fix is pull, pin, retag, redeploy, or release-policy correction.
3. Preserve the original identities
docker context show
docker version
docker inspect affected-container --format \
'name={{.Name}} requested={{.Config.Image}} localImageID={{.Image}} created={{.Created}}'
docker image inspect IMAGE_ID --format \
'ID={{.Id}} tags={{json .RepoTags}} digests={{json .RepoDigests}} os={{.Os}} arch={{.Architecture}} created={{.Created}}'
docker buildx imagetools inspect registry.example/team/app:stable
Do not run an always-pull command until this baseline is saved. Pulling may change the local tag mapping and make the original stale-cache condition harder to prove.
4. Intentionally broken example: two hosts, one tag, two releases
app:stable yesterday when it resolved to digest A. The
publisher moved stable to digest B this morning. Host B
started after the move. Host A uses default
--pull=missing and already has the tag cached.
Host A can reuse its cached content while Host B pulls B. Both
deployment configs still say app:stable. The fix is not
“restart Docker.” Capture both image identities, verify current
registry resolution, then decide whether both should pin A, both
should move to approved B, or the release alias was moved
incorrectly.
5. Failure matrix
| Symptom | Likely layer | Evidence | Least-destructive correction |
|---|---|---|---|
| One host runs old bytes under same tag | Pull policy/local cache | Container image ID + RepoDigest + pull timestamp | Deploy approved digest or intentional pull after preserving evidence. |
| amd64 works, arm64 fails | Platform manifest | Index + child digest + architecture | Repair/release the failing platform artifact; do not blindly rebuild all platforms. |
| “Same release” has two digests | Release process | Push logs, build refs, source SHA | Stop rebuilding during promotion; choose one approved digest. |
| Pin never receives security update | Dependency maintenance | Base digest age + advisory/update evidence | Review and test a new digest; do not unpin silently. |
| Audit has only local image ID | Evidence design | Missing RepoDigest/registry proof | Add registry-qualified digest capture to pipeline. |
6. Container name and tag are both mutable human labels
A container name can be removed and reused for a different container ID. An image tag can move to a different digest. During an incident, preserve immutable IDs and timestamps in addition to names. Human labels are for navigation; IDs and digests are for correlation.
7. Digest pinning can preserve vulnerable bytes perfectly
Reproducibility and security maintenance are separate concerns. A digest pin protects against unexpected drift, but it also prevents automatic drift toward a patched base. A mature workflow periodically detects a newer approved base, proposes the digest change, rebuilds, retests, rescans, and records a new release identity.
8. Troubleshooting shortcuts to reject
- Do not delete all local images or run broad prune commands before recording IDs/digests.
- Do not rebuild the release merely to see whether the problem disappears.
- Do not overwrite a production release tag to “put it back” without first preserving both old and current resolutions.
-
Do not switch to
latestor always-pull as a substitute for deciding which digest is approved. - Do not disable registry TLS or weaken daemon trust settings to inspect an unrelated endpoint.
9. Performance: freshness has a cost, but identity comes first
Always pulling a mutable tag adds registry latency and bandwidth,
while missing can reuse local bytes. Time-based Compose
policies balance freshness and traffic for developer workflows.
Production optimization should avoid repeated downloads by staging
known digests, not by sacrificing release identity. Measure transfer
sizes and pull latency separately from correctness.
10. Recovery pattern
Once evidence identifies the approved digest, create a new container or deployment from that digest. Verify the container’s requested reference and local image ID, application health, and external behavior. Preserve the incident note explaining why the mutable alias differed. Then fix the promotion/pull policy so the same ambiguity cannot recur.
Knowledge check
Why should you inspect a stale host before running an always-pull command?
Because the pull can change local reference state and destroy evidence of what the host previously had cached.
If amd64 and arm64 fail differently under one tag, what should you compare?
The shared index digest plus each platform-specific manifest digest and test evidence.
Does an exact digest prove the image is vulnerability-free?
No. It proves identity, not security quality.
Why is rebuilding a poor first troubleshooting action for a release-identity incident?
It creates new content and can hide whether the original artifact or promotion process was wrong.
What immutable values should accompany human labels during incident capture?
Container ID/local image ID, registry digest(s), timestamps, and platform identity.
Official references and version notes
-
docker image ls— digest display, local image IDs, and digest-addressed pull/create/run examples. -
docker image inspect— low-level local image metadata, including platform-aware inspection on capable stores. -
docker run— current--pull=missing|always|neversemantics. -
Compose
pull_policy—always,never,missing,build,daily,weekly, andevery_<duration>. - Docker build best practices — pinning base images by digest, controlled updates, and auditability tradeoffs.
-
docker buildx imagetools inspect— registry-side manifest/index and platform inspection. - Image digests — manifest-list/index versus per-platform image digest distinctions.
- OCI Image Index Specification — immutable index descriptors and platform selection.
- OCI Image Manifest Specification — config and layer descriptors addressed by digest.
- Docker Engine 29 release notes — Engine 29.8.1 baseline used when authoring this chapter.
- Buildx releases and BuildKit releases — current build-tool release history.
Version-sensitive statements were rechecked against primary documentation on 2026-09-21. The authoring baseline is Docker Engine 29.8.1, Buildx 0.37.1, BuildKit 0.33.0, and Dockerfile frontend 1.27.0, but every executable lab records the versions and context actually present. Registry tags, platform indexes, local image stores, and Compose behavior can evolve independently; prefer observed digests and current primary documentation over memorized output.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.