Go statically builds its standard library into each binary, so a standard library finding in a container image is fixed by rebuilding the binary with a patched Go release. Updating OS packages in the image will not change it. Confirm the build version with go version, rebuild, and rescan.
Why an OS update does nothing
Most Go programs are compiled into a single executable. The standard library code the program uses is part of that file. The scanner reads build information embedded in the binary, finds the Go version that built it, and matches that against known vulnerabilities in the standard library.
The Go documentation for go version says it reports the Go version used to build each named file, and with the module flag prints the embedded module information too. So you can check the same data the scanner sees.
docker create --name tmp myimage@sha256:abc123
docker cp tmp:/app/server ./server
docker rm tmp
go version -m ./server
The first line shows the toolchain version. The lines after it list module dependencies and their versions.
Steps to fix it
- Read the toolchain version from the binary and the advisory's fixed Go version.
- Update the build stage image or the toolchain setting to a patched release. The Go toolchain documentation describes how a
GOTOOLCHAINsetting chooses the toolchain, which matters if your build downloads a newer one automatically. - Rebuild the binary in a multi-stage build and copy it to a small final image.
- Rescan the new image digest and check
go version -magain. - Redeploy.
The final stage may be a minimal image with no Go tools at all. That is fine. The fix is in the build stage, because that is where the compiler lives.
Module dependencies versus the standard library
Findings on modules listed by go version -m are fixed in go.mod and the lockfile like any dependency. Findings on the standard library are fixed by the toolchain. The path in the scan row helps: a module path points to a dependency, while the name stdlib or a package from the Go standard library points to the toolchain. Different owners often handle each, so label them separately.
Can a scanner tell if the vulnerable function is used?
Partly. The govulncheck documentation says that on a compiled binary it uses symbol information to find mentions of vulnerable functions, but it cannot show call stacks and may report false positives for code present in the binary but never called. For binaries where symbols cannot be extracted, it reports vulnerabilities for every module the binary depends on. It also notes that for binaries built before Go 1.18 it reports just standard library issues. So a binary scan is a good first filter, not a final reachability answer. Compare approaches in govulncheck versus a version based scanner.
Checking the fix landed
- The
go versionline shows the patched release. - The new image digest differs from the old one.
- The rescan no longer lists the finding.
- Every service built from the same Dockerfile template has been rebuilt, since each binary carries its own copy.
Quick check
Do I need Go installed in the final image to patch it?
No. Patching happens in the build stage. The final image just needs the compiled binary.
Why does the same finding return after I just bumped the base OS?
The binary was not rebuilt. It still carries the old standard library, so the finding stays until you recompile.
Sources
Last reviewed: 19 October 2026.