THIS EXPLANATION
THE ROOM
CDA·213 Computing, Data & AI 6 MIN · 8 STATIONS

Tags versus digests

A Socratic walk-through of tags versus digests — reasoned out one step at a time, not lectured.

abcdefgh
a

The question we started with

THE QUESTION #

Why can the same name fetch two different things a week apart?

You deploy myapp:1.4.2 on Monday. On Friday, a new machine joins the fleet, pulls myapp:1.4.2, and runs something different — different binary, different behaviour, same name. Nobody edited a config file. The version number did not move.

The instinct is that something went wrong. It did not: the system behaved exactly as designed. So the question worth asking is what a tag was ever promising, and why we so readily heard a promise it never made.

b

Reasoning it through

REASONING #

Ask what a registry has to store. It has to store image content, and it has to let people ask for it by some name. Those are two different jobs, and it is worth noticing they could be done by the same identifier or by two.

Take the content first. An image is a manifest listing its layers and its configuration. Give a registry the ability to name that manifest by the hash of its own bytes — sha256: followed by sixty-four hex characters — and something strong follows. That name cannot be reassigned, because changing the content changes the hash. It is not a pointer to the content; it is the content, compressed to a fingerprint. Ask for a digest and either you get exactly those bytes or you get an error, and the client can verify which by hashing what arrived.

Now the second job. Nobody can remember sha256:9b2c.... Humans need a name they can type and reason about, and more than that, they need a name that can move1.4 should be able to mean the newest patch in that line, and latest should be able to mean the newest release. A name that moves is precisely a name that is not the content.

So a tag is a mutable pointer: an entry in the registry mapping a human-readable label, within a repository, to one manifest digest. Pushing the same tag again rewrites the entry. That is not a loophole; it is the entire purpose of having a second kind of name.

Follow this through your Monday-to-Friday puzzle and it dissolves. Somebody rebuilt and re-pushed 1.4.2 — perhaps a patched base image, perhaps a rerun of a failed pipeline. The digest changed. The tag now points somewhere else. Monday's machine still runs the old image because it already has those bytes locally; Friday's machine resolves the tag afresh and gets the new ones. Two machines, one name, two images, and no error anywhere.

Which suggests the rule. Use a tag where you want a choice made later — browsing, documenting, telling a human which line to follow. Use a digest where you want a fact fixed now — what a running deployment consists of, what an audit refers to, what a security scan's result is attached to. The reference form myapp@sha256:9b2c... pins it, and the two can be combined as myapp:1.4.2@sha256:9b2c..., which reads as "the thing that was 1.4.2, and here is exactly which thing that was".

One complication worth being accurate about. For a multi-architecture image, the digest a tag points at is usually not an image manifest at all but an index — a manifest list naming one per-platform manifest for each architecture. So myapp@sha256:... is fully deterministic and still resolves to different bytes on an arm64 host than on an amd64 one. That is not tag mutability sneaking back in; it is the index doing its job, and the reference remains reproducible in the sense that matters, since the index itself cannot change.

And latest? It is not special to the registry in any way. It is an ordinary tag with an ordinary name, distinguished only by being the default the client appends when you supply none. Everything unfortunate about it follows from that default, not from any registry behaviour.

c

The analogy

THE ANALOGY #
THE FIGURE

Think of a library where every book has a shelf mark that is a fingerprint of its exact printing — change one comma and it is a different mark. Alongside that, the desk keeps a list of nicknames: "the recommended edition", "the 2024 printing". Ask for a nickname and the librarian looks it up and fetches whatever it currently points to. Ask for a shelf mark and you get that exact printing or nothing.

When a corrected impression arrives, the desk quietly repoints "the 2024 printing" at it. Two readers who asked by nickname a week apart hold different books and both believe they followed the same instruction.

WHERE IT BREAKS DOWN

a reader can open the book and see it is not the one they expected, whereas a container image gives you no such tell — the tag you asked for is what the running system reports, so nothing surfaces the substitution unless you were already recording digests.

d

Clarifying the model

THE MODEL #

Three refinements.

First, the misconception this corrects: version tags are read as immutable because they look like version numbers, and semantic versioning trains us to treat 1.4.2 as a fixed artifact. Nothing in the registry enforces that. It is a convention among the people pushing, and conventions are broken by rebuilds, by mirrors, and by pipelines that retry.

Second, "pin your digests" is not the whole answer either, because a pinned digest never picks up a security fix. The workable arrangement is not to choose one but to separate the roles: let a tool resolve tags to digests deliberately at a chosen moment, record the resolved digest, and deploy that — so updates happen when someone decided they should, rather than whenever a machine happened to pull.

Third, digests give you identity, not trust. A digest proves you received the bytes you asked for; it says nothing about who produced them or whether they are safe. That is a separate mechanism — signing, attestation, provenance — and it is worth keeping the two apart, because "we pin digests" is often offered as a security claim when it is really an integrity and reproducibility claim.

e

A picture of it

THE PICTURE #
Tags versus digests
Tags versus digests Follow the cardinality marks rather than the boxes. A repository holds many tags and many manifests. The relationship that matters is the one between them: many tags may point at one manifest, and that arrow is the only mutable thing in the diagram -- everything else is fixed by content. The one-to-one between a manifest and its digest is why a digest cannot lie: the name is computed from the thing. The index at the bottom is why one digest can still yield different bytes on different architectures without any of this changing. {"generator":"mermaid-svg-renderer@3.2.1","source":"../Socrates/.diagram-cache/_src/tags-versus-digests.md","sourceIndex":1,"sourceLine":4,"sourceHash":"4f5d7f618d378ea6328d866e596803dad2c47723131fba21b16b40744a0c3128","diagramType":"er","layoutVariant":"source","repairedDuplicateIds":[],"motion":"entrance-with-reduced-motion-fallback","presentation":"editorial","attempt":1,"viewBox":{"x":0,"y":0,"width":720,"height":943},"qa":{"passed":true,"findings":[]}} holds many stores points at, can move named by hash lists in order one per platform REPOSITORY E02 TAG string name boolean mutable MANIFEST E04 DIGEST string algorithm string hex LAYER INDEX

How to readFollow the cardinality marks rather than the boxes. A repository holds many tags and many manifests. The relationship that matters is the one between them: many tags may point at one manifest, and that arrow is the only mutable thing in the diagram — everything else is fixed by content. The one-to-one between a manifest and its digest is why a digest cannot lie: the name is computed from the thing. The index at the bottom is why one digest can still yield different bytes on different architectures without any of this changing.

f

What became clearer

WHAT CLEARED #
WHAT CLEARED

A registry keeps two kinds of name for the same content, and they were built for opposite purposes: a digest is the content's own fingerprint and cannot be moved, while a tag is a pointer whose whole value is that it can. Nothing goes wrong when a tag changes — what goes wrong is expecting a movable name to hold still, and the fix is to decide deliberately when the resolution from one to the other happens.

g

Where to go next

ONWARD #
  • Image signing and provenance attestations, and what they add on top of a digest.
  • Admission controllers that require digest references in a cluster.
  • Manifest lists in detail, and how a client selects the right platform entry.
h

Key terms

TERMS #
TermWhat it means
Taga mutable, human-readable label within a repository that points at one manifest digest.
Digestthe hash of a manifest's bytes, serving as an immutable, self-verifying name for that content.
Manifestthe document listing an image's layers and configuration.
Index (manifest list)a manifest naming one image manifest per platform, so a single reference serves several architectures.
Content addressingnaming data by a hash of the data itself, so the name and the content cannot disagree.

Every term the collection defines is gathered in the glossary.

Nearby on the shelf

4