Safeguard
Security Guides•

Why does a fixed vulnerability keep showing up in my scans?

A flaw you fixed can reappear in later scans for six common reasons, from old copies to indirect packages. Here is how to find which one and stop it.

Safeguard Security Team
8 min read

A fixed vulnerability usually reappears because the fix did not reach everywhere the flawed software lives: an old copy in another project, a stale build, an indirect package pulling the old version back, or a scan reading outdated data. Find which place still holds the old version, then fix that place.

TL;DR

  • Reappearing findings are usually real, not scanner mistakes.
  • Check six places: other projects, old images, indirect packages, lock files, caches, and merge conflicts that undid your change.
  • Rescan the exact thing that was deployed, not just the code on your laptop.
  • Add a check that blocks the old version from coming back.

Why does this happen so often?

Software is copied in many places. The same package can sit in your main app, a helper tool, a test setup, a container image and a backup branch. Fixing one copy leaves the others. A scanner reads every place it is pointed at, so it keeps reporting the ones you missed.

Think of a leaking pipe. You fix the one under the kitchen sink. The inspector returns and finds the same type of leak under the bathroom sink, because the same builder used the same pipe in both. The inspector is not wrong, and neither were you. The fix just did not cover every room.

A few terms first. A vulnerability is a flaw someone could misuse. A dependency is a package your code relies on. An indirect dependency, also called a transitive dependency, is a package that one of your dependencies relies on. You did not choose it directly, but you still ship it.

What are the six usual causes?

CauseWhat is happeningHow to check
Another project uses itThe fix was made in one repository onlySearch all repositories for the package name
Old container imageThe deployed image was built before the fixCheck the build date and rebuild
Indirect packageAnother package keeps asking for the old versionLook at the dependency tree for who requires it
Lock file not updatedThe file that pins exact versions still lists the old oneRegenerate the lock file and commit it
Cache or stale buildThe build tool reused an old copyClear caches and rebuild from clean
Change was undoneA merge or a revert brought the old version backReview recent history for the file

Cause 1: another project uses the same package

This is the most common one in teams with several repositories. Search every repository you own for the package name, not just the one where the alert fired. A written list of software, as described in how to start vulnerability management, makes this search quick.

Cause 2: the running image is older than the fix

A container image is a packaged copy of an application and everything it needs to run. Images are built at a moment in time. If you fixed the code but never rebuilt and redeployed the image, the running version still has the flaw. Scan the image that is actually running, and compare its build date with the date of your fix.

Cause 3: an indirect package keeps pulling in the old version

You upgrade the package you control, but another package you use still asks for the old version of the vulnerable one. The package manager may pick the old one. To see which package asks for it, view your dependency tree. Then either upgrade the outer package, or use your tool's setting that forces a specific version, often called an override or resolution. Test after forcing, because the outer package may not like the change.

Cause 4: the lock file still lists the old version

Many tools write a lock file, a file that records the exact version of every package so builds repeat exactly. If you edit the main settings file but do not refresh the lock file, the build still installs the old version. Regenerate the lock file and commit it with the change.

Cause 5: caches and stale builds

Build systems cache downloads to save time. A cache can serve an old copy. Clear it and rebuild from a clean state, then scan the new output.

Cause 6: someone undid the fix

A merge from an older branch, an automated update that downgrades a version, or a revert can quietly restore the old package. Check the recent history of the file that sets the version.

How do you find the cause quickly?

Ask these questions in order.

  1. Is the new finding in the same place as the old one? If not, it is a different copy. Go to cause 1.
  2. Does the scan target the deployed artifact or only source code? If it scans an image, check cause 2.
  3. Does the dependency tree show the package pulled by something else? That is cause 3.
  4. Does the lock file list the old version? That is cause 4.
  5. Does a clean rebuild change the answer? If yes, it was cause 5.
  6. Does the history show a revert? That is cause 6.

A worked example with invented numbers

These numbers are invented to show the process, not drawn from a real case.

On Monday you upgrade a package from 1.2.0 to 1.2.4 to remove a flaw in the web app. The scan clears. On Friday the weekly scan shows the flaw again, with 3 findings.

FindingWhereCause
1Billing service repositoryCause 1: never upgraded
2Production image, built last TuesdayCause 2: image older than the fix
3Web app, via a reporting pluginCause 3: the plugin requires 1.2.0

You upgrade the billing service, rebuild and redeploy the image, and update the reporting plugin to a newer release that accepts 1.2.4. Three findings, three different causes, one root issue: the fix was applied in one place only. After the rescan, the count is zero.

How do you stop it from coming back?

  • Scan on every change. A rescan on each pull request catches a downgrade before it ships. Read about continuous vulnerability management.
  • Set a rule. Use a policy that blocks a build when it contains a version known to be vulnerable.
  • Scan what you deploy. Include built images and not only source code.
  • Keep one inventory. One shared list of where each package is used turns step one into a search instead of a hunt.
  • Record each fix. Write down which repositories and images were updated.

If you want to know whether a repeat finding might be a false alarm, see the false positives FAQ. A repeat finding is more often real than not, but a mismatch is possible, for example when a package was fixed in a way the database does not recognize.

Try it yourself

Click through it at your own pace, or open it full screen. Look for how repeated scans catch a version that comes back after it was fixed.

How can Safeguard help?

Safeguard scans dependencies and builds SBOMs for your projects, so the question of where else a package lives can be answered from one place. Policies and gates can block a pull request that reintroduces a known flaw. Because scans can run on each change, a version that returns is caught on the next run and not weeks later. You can see what a scan looks like with the free scan at gold.safeguard.sh/scan.

Quick check

Is a reappearing finding a scanner bug?

Rarely. Most of the time another copy, an old image or an indirect package still has the old version. Check those first.

What is a lock file and why does it matter?

It records the exact version of every package so that builds repeat exactly. If it is not updated, the build can still install the old vulnerable version.

How do I know which package pulls in the old version?

Look at your dependency tree. Most package tools can print it and show which package requires the vulnerable one.

Should I scan the code or the deployed image?

Both. Code shows what you intend to ship. The image shows what is actually running.

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.