Safeguard
Security Guides•

Why do two Python versions appear in one container scan?

Non-slim Python images carry a distro Python and an image Python. Each has its own findings and its own fix. Here is how to tell them apart.

Safeguard Security Team
4 min read

Many Python images contain two interpreters: one installed by the operating system and one built for the image. A scan reports each separately, with different packages and different fixes. The image Python is replaced by moving to a newer image tag, and the distro Python by refreshing the OS layer.

Where each one lives

The Docker official Python image documentation explains this for the non-slim variants. The image provides its own Python at /usr/local/bin/python, which is first on the path. Because the non-slim variants build on a larger base that includes development tooling, there is also a distribution provided python at /usr/bin/python or /usr/bin/python3. The docs say the distro one cannot be safely removed, since many distribution tools are written against it.

So your application runs the image Python, while the scan sees both.

How to read the paths in a finding

The file path or package location in a finding points to the owner.

Path patternInstalled byWho fixes
/usr/local/bin/python and /usr/local/lib/pythonX.YThe image buildNewer image tag or rebuild on a patched tag
/usr/lib/python3 and dist-packages under itOS package managerOS updates in the base layers
/usr/local/lib/pythonX.Y/site-packagespip, in your buildYour requirements file

Debian's Python policy says public Python 3 modules from the system are installed in /usr/lib/python3/dist-packages, and a separate directory under /usr/local is reserved for modules the local administrator installs. Python's own site documentation describes site-packages under the prefix, for example /usr/local/lib/pythonX.Y/site-packages on a typical Unix build.

Does the distro Python matter if my app never runs it?

It can still matter. It sits in the image, it can be run by anyone who gets a shell, and some OS tools call it. But the priority is lower than a flaw in the interpreter and packages your service actually loads. Reachability, meaning whether the vulnerable code runs in your application, is the right tiebreaker. See installed is not exploitable.

If you want the distro Python gone, the practical options are a slim variant or a multi-stage build that copies just what the app needs into a smaller final image.

Steps to sort a Python image scan

  1. Filter findings by path prefix: usr/local versus usr/lib.
  2. Mark each group with an owner: image maintainer, OS maintainer, app team.
  3. For the interpreter, check for a newer patch tag of the same minor version and rebuild with a fresh pull.
  4. For pip packages, update the pinned versions and regenerate hashes.
  5. Rescan the new digest and confirm both interpreters.

You can print what the image sees at run time.

docker run --rm myimage which -a python python3
docker run --rm myimage python -c "import sys; print(sys.version); print(sys.path)"

What to put in the ticket

Name the interpreter path in the ticket title, such as "Python at /usr/local/bin" or "dist-packages under /usr/lib". It saves the reader a guess about which of the two pythons is meant. Add the digest, the finding id and the fixed version, and say which owner group the path maps to.

If the finding is on the image Python, check whether the tag you build from has a newer patch release for the same minor version. If it does, bump the tag and rebuild with the pull flag. If it does not, check whether a newer minor release is acceptable for your code, and plan the upgrade with your test suite in front.

For the distro Python, the fix usually arrives with the next OS package update, so a rebuild with a fresh pull of the base tag is the lever. If the OS vendor has marked the issue as deferred or ignored, the question becomes whether you need that interpreter in the final image at all.

Quick check

Will pip install upgrade the OS Python packages?

No. Pip installs into the interpreter's own site-packages. OS packages under dist-packages are managed by the OS package manager.

Is a slim image free of the second Python?

Slim variants are smaller and do not use the same large base, but check your own image with the which command rather than assuming.

Sources

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.