Skip to main content
reliability · kubernetes

Workloads pinned to :latest or no tag at all

resource types
3
rule IDs covered
9
severity
medium

What does ZopNight detect here?

A container image referenced as :latest or with no tag resolves to whatever the registry holds at pull time. Two pods in 1 ReplicaSet can run different code, and a rollback does not roll anything back. ZopNight checks 3 workload kinds.

Signal and threshold

How ZopNight evaluates Workloads pinned to :latest or no tag at all.
Field Value
Rule IDsRC-1711 · RC-1811 · RC-1911 · RC-1712 · RC-1812 · RC-1912 · RC-1713 · RC-1813 · RC-1913
Categoryreliability
Severitymedium
Metricnone — pure configuration read
Sourceinternal/rules/k8s/image_latest.go

The same manifest, different code

:latest is not a version. It is a mutable pointer, resolved when the kubelet pulls, so the image a pod runs depends entirely on when it started.

That produces the failure mode people find hardest to debug: two pods in the same ReplicaSet running different builds. One started before the tag moved, one after, both report the same image string, and they behave differently.

Omitting the tag entirely is identical, since Kubernetes defaults to :latest.

Rollback stops working

This is the consequence that matters most in an incident.

kubectl rollout undo restores the previous pod spec. If both the current and previous specs say myapp:latest, the rollback restores an identical spec and pulls whatever latest points at now, which is the broken build you are trying to escape.

The rollout reports success. Nothing changed. That discovery, mid-incident, is the argument for this rule.

imagePullPolicy interacts badly

With :latest, the default pull policy is Always, so every pod start re-pulls. That means a node failure at 3am silently upgrades the rescheduled pod to whatever is newest: an unplanned deploy triggered by an unrelated event.

With an explicit tag the default becomes IfNotPresent, and behaviour is predictable.

Digests are stronger than tags

An immutable tag is good; a digest is absolute:

Terminal window
image: myapp@sha256:abc123...

A digest cannot be repointed by anyone. For anything where supply-chain integrity matters, that is the only reference that guarantees the bytes you tested are the bytes that run.

Filtering images for latest or no tag

Terminal window
kubectl get deploy,statefulset,daemonset -A -o json | jq -r '
.items[] | . as $w | .spec.template.spec.containers[]
| select((.image | test(":") | not) or (.image | endswith(":latest")))
| "\($w.kind) \($w.metadata.namespace)/\($w.metadata.name): \(.image)"'

Enforcing it

Tag immutability in the registry stops latest moving under you. ECR, GAR and ACR all support it, and it is off by default in each.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

417 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

417 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·