When a Docker image is configured with both a version tag and a cryptographic digest (e.g., image:tag@sha256:…​), Docker prioritizes the digest and completely ignores the version tag. While technically valid, this practice introduces severe documentation drift. The visible version tag may not actually match the underlying image pointed to by the digest.

Why is this an issue?

Misleading Documentation: The Dockerfile becomes a source of misinformation. Over time, the tag and the digest can drift, meaning the tag says one thing while the container runs another.

Review & Maintenance Confusion: During code reviews, auditing, or debugging, developers will naturally trust the explicit version tag. If an issue arises, they may waste hours troubleshooting the wrong version of an image because the true image identity is hidden behind the ignored tag.

False Sense of Security: It obscures dependency tracking and vulnerability scanning, as teams might think they are on a patched version based on the tag, while the digest pulls an older, vulnerable build.

How to fix it

To avoid this issue, it is recommended to specify either the version tag or the digest of the image. For example, instead of my-image:1.2.3@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d, it is better to use my-image:1.2.3 or my-image@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d.

For even more control and traceability, the digest can be used instead of the version tag. This will pin the image to a specific immutable version, ensuring reproducible builds, but will also prevent automatic security updates that would come from using a version tag. An example would be my-image@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d.

Additional information can be found in the Resources section below. See also a related rule {rule:docker:S7023}.

Code examples

Noncompliant code example

FROM my-image:1.2.3@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d

Compliant solution

FROM my-image:1.2.3

or:

FROM my-image@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d

How does this work?

This way, the version of the Docker image is pulled using either the digest or the version tag, ensuring that the specified version information accurately represents the image that will be pulled.

Going the extra mile

Additionally, when only the digest is specified, a comment can be added to specify the version of the image to improve readability. For example,

# my-image-1.2.3
FROM my-image@sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d

Resources

Documentation

Articles & blog posts