What to do when a base image comes back end-of-life
An eol or deprecated-image finding is a prioritization signal, not an incident report. Here is how to triage findings across more than one Dockerfile, plan the upgrade rather than just bumping the tag, and what to document if you cannot upgrade today.
Triage by exposure first, by date second
A scan across a monorepo commonly returns several findings at once, and not every finding carries the same risk even at the same days-past-end-of-life count. Work the list in this order:
| Priority | What it looks like | Why it comes first |
|---|---|---|
| 1 — highest | An internet-facing service, on a deprecated-image or eol finding | Directly reachable, and the release line is either discontinued outright or already unpatched |
| 2 | An internal service handling untrusted input (uploads, webhooks, third-party feeds), on eol | Not directly exposed, but processes data it does not control |
| 3 | An internal batch job or CI-only image, on eol | Narrower attack surface, but still unpatched and worth a planned upgrade |
| 4 — lowest | Any of the above on eol-soon | Still supported today; the work is scheduling the upgrade before the date arrives, not an urgent fix |
This tool does not know which of your services is internet-facing or what data it handles — it only classifies the base image reference. Apply your own exposure knowledge on top of its output; do not read the table above as a re-ranking the tool performs for you.
Plan the upgrade — a major-version bump is a real change
A patch-level bump within the same major release (node:18.19
to the latest node:18 point release) is usually safe to
rebuild and ship. Moving across a major version line —
node:18 to node:22, python:3.9 to
python:3.12, an Ubuntu codename change — can change
runtime defaults, drop deprecated APIs, or bring newer versions of
whatever the base OS installs by default. Treat it the way you would any
dependency major bump:
- Read the target release's own changelog or migration notes for breaking changes, not just its end-of-life date.
- Bump one Dockerfile or one stage at a time rather than a repo-wide find-and-replace, especially across a multi-stage build where a builder stage and a runtime stage can reasonably land on different release lines.
- Rebuild and run your existing test suite against the new image before merging — a clean build is not evidence the runtime behaves the same.
- Re-scan afterward. A successful upgrade should turn the finding into
supported, not just move it further from today's date.
If you cannot upgrade today
Sometimes the upgrade is real work — a framework version tied to the runtime, a dependency that has not caught up yet, a freeze window. Three things are worth doing even when the fix has to wait:
- Pin to the image's current exact content digest. This does not change its end-of-life status, but it stops the reference from silently moving further from the last point it was patched while you wait. See Docker Base Image Pin Check for that specific question.
- Write the finding down somewhere durable. This tool's report lives in your browser tab and this page saves nothing on your behalf — open a ticket or note it in whatever tracks technical debt on your team, with the release line and the end-of-life date from the report.
- Set a re-check date, and prefer wiring
check.py --fail-on-riskinto CI over relying on someone remembering to re-run this page. A documented, time-boxed exception is a defensible decision; an undocumented one is just drift.
Common questions
Does an end-of-life finding mean my image is already vulnerable?
No. It means the release line's publisher has stopped shipping security patches for it, so any vulnerability discovered from that date forward will not be fixed upstream. An image on that release line can still show a clean vulnerability scan today — the risk is that nobody is looking for new issues in it any more, not that a specific one is already known. Treat it as a prioritization signal, not an incident.
Which finding should I fix first?
Triage by exposure before you triage by how long a release has been end-of-life. An internet-facing service on an end-of-life image outranks an internal batch job on one that went end-of-life more recently, even if the batch job's finding looks more urgent by date alone. Within a tier, deprecated-image findings (a repository discontinued outright, not just a version that stopped getting patches) and eol findings outrank eol-soon warnings.
Can I just bump the tag and rebuild?
Sometimes, for a patch-level bump within the same major version. A bump across a major version line (node:18 to node:22, python:3.9 to python:3.12, an Ubuntu codename change) can carry breaking changes in the runtime or the base OS's own package versions, so treat it as a real change to test in CI, not a same-day find-and-replace across every Dockerfile that references the old tag.
What if I cannot upgrade right now?
Pin the current image to its exact content digest so it stops moving further from the point where it was last patched, note the finding somewhere it will not be forgotten (a ticket, not just this page's report, which nothing here saves for you), and set a re-check date. That is a documented, time-boxed exception, not a fix — the release line is still unpatched upstream for as long as the pin stands.
Want the accuracy question instead — where the dates come from and what a clean scan does and doesn't mean? See the tool's own FAQ, or how this compares to a vulnerability scanner and to checking end-of-life dates by hand.