For the complete documentation index, see llms.txt.

Resolve a scanner finding for a CVE Chainguard has fixed

What to check when the Chainguard Console or a security advisory says a CVE is fixed, but your vulnerability scanner still reports it.
  8 min read

Sometimes the Chainguard Console or a Chainguard security advisory reports a CVE as fixed, but your vulnerability scanner still reports it in the same image. When this blocks a CI security gate, the cause is usually a mismatch between the image you scanned, the data your scanner uses, and Chainguard’s advisory data. Work through the checks on this page in order; they’re arranged so that the most common causes come first.

This page covers findings in packages that Chainguard ships. That includes Go modules, Java archives, and other language components inside a Chainguard APK package, because Chainguard records advisories against the APK package that contains them. For a dependency that your own build adds to the image, see Dependencies that your build adds.

Work through the causes in order

Each of the following checks rules out one cause. After each one, scan again; stop when the finding clears.

Confirm that you scanned the current image

A tag such as latest moves to a new digest each time Chainguard rebuilds the image. If your pipeline cached an older image or pinned an older digest, the scanner reports CVEs that later builds fixed.

Scanning by tag can also pick up an old copy of the image. Some scanners, including Grype, scan an image from the local Docker daemon when one with that tag exists, rather than pulling the current image from the registry.

  1. Get the digest that the tag points to now:

    crane digest cgr.dev/<organization>/<image>:<tag>

    The crane command uses the same registry credentials as docker. If it can’t authenticate, run chainctl auth configure-docker first.

  2. Compare that digest with the image’s repository digest in your scanner’s output. Without the --platform flag, crane digest returns the digest of the multi-architecture image, which is the value that Docker and most scanners report as the repository digest. A digest for a single architecture, such as the one that crane digest --platform returns, is a different value even for the same image.

  3. If the digests differ, scan the current image from the registry by digest, and specify the platform that you deploy:

    grype registry:cgr.dev/<organization>/<image>@sha256:<digest> --platform linux/amd64

Compare the installed package with Chainguard’s fixed version

A Chainguard advisory records the version of each package that contains the fix. Chainguard records this separately for each package, including each subpackage built from the same source, and separately for each architecture. A parent package and its subpackages can have different statuses for the same CVE. For example, in one advisory the x86_64 bind-libs subpackage is fixed, while the parent bind package waits on an upstream fix.

  1. In your scanner’s output, find the exact name of the flagged package, its installed version, and the architecture of the image that you scanned.

  2. Find Chainguard’s fixed version for that package and architecture, in any of the following places:

    If no fixed version is recorded for that package and architecture, Chainguard hasn’t fixed the CVE in that package, and the finding is valid.

  3. Compare the two versions using APK version ordering, which doesn’t always match the order you might expect. For example, a version with a pre-release suffix, such as 1.3.2.1_rc20260601-r0, sorts before 1.3.2.1-r0. To compare two versions, run apk version -t in a Wolfi container:

    docker run --rm cgr.dev/chainguard/wolfi-base apk version -t <installed-version> <fixed-version>

    The command prints < if the installed version is earlier than the fixed version, = if they’re the same, and > if the installed version is later.

If the installed version is earlier than the fixed version, the finding is valid for that image. Update to an image build that contains the fixed version.

If the installed version is the fixed version or later, that package is fixed for this CVE. Before you treat the finding as resolved, confirm that the scanner isn’t also reporting the CVE against another package or architecture in the image. The remaining checks explain why a scanner can still report a fixed package.

Confirm that your scanner reads Chainguard’s advisory data

A scanner can apply Chainguard’s fixed versions and “not affected” determinations only if it reads Chainguard’s advisory data. A scanner that doesn’t read it relies on upstream or third-party vulnerability data, which describes upstream release versions rather than Chainguard’s package builds. Such a scanner keeps reporting CVEs that Chainguard has fixed, and updating its database or waiting doesn’t change the result.

Check whether your scanner appears in the list of scanners that support Chainguard, and whether your scanner’s documentation requires any configuration to scan Wolfi or Chainguard packages. If your scanner doesn’t support Chainguard, ask your scanner vendor to add support.

How the scanner analyzes the image also matters. A scanner identifies the packages in a Chainguard image by reading the APK database at /usr/lib/apk/db/installed, which only the complete image filesystem contains. A scanner that analyzes image layers individually, or a custom image that removes the APK database, leaves the scanner to identify software by other means, such as file signatures or CPE matching. Chainguard’s advisories can’t correct those matches.

Update your scanner’s vulnerability database

Scanners match packages against a local copy of a vulnerability database. A copy that predates the advisory doesn’t contain the fix. Check when your database was built, and update it if it’s out of date. For example, with Grype:

grype db status
grype db update

The Built field in the output of grype db status shows when the database was built. For other scanners, see the scanner’s documentation for how to update its database. In CI, also confirm that the pipeline doesn’t restore an old database from a cache.

Allow time for new advisory data to reach your scanner

Chainguard publishes advisory feed updates several times a day. Your scanner’s vendor then ingests that data and publishes its own database update on its own schedule. A fix that Chainguard published recently can take some time to appear in your scanner’s results, even when your database is up to date. If the advisory is recent, scan again later.

If the scanner’s fixed version doesn’t exist in Chainguard repositories

A scanner can report a “fixed in” version that you can’t find in any Chainguard package repository. This happens when the scanner takes its fixed version from somewhere other than Chainguard’s advisory, such as an upstream release range, another distribution’s packaging, or its own inference about the next release.

Chainguard’s fixed version doesn’t have to match an upstream release. When an upstream project fixes a vulnerability without publishing a release, Chainguard can ship the fix as a backported patch or as a build of an unreleased upstream revision. The version string of that build reflects how Chainguard packaged it, not the next upstream release number.

The fixed version in Chainguard’s advisory is the one that applies to Chainguard packages. Compare your installed version with that value, as described in Compare the installed package with Chainguard’s fixed version. If your scanner reads Chainguard’s data and still reports a fixed version that Chainguard’s advisory doesn’t contain, contact support.

Look up the fixed version in the advisory feed

Chainguard publishes its security advisories in the OSV format. Scanners read this feed, so you can use it to see exactly what Chainguard has recorded for a CVE. For more information about the available feeds, see Programmatic access.

The following steps use curl and jq.

  1. Find the Chainguard advisory IDs for the CVE. The feed index lists each advisory’s ID along with the upstream identifiers, such as CVE and GHSA IDs, that it covers:

    curl -s https://advisories.cgr.dev/chainguard/v2/osv/all.json \
      | jq -r --arg cve "CVE-<year>-<number>" '.[] | select(.upstream | index($cve)) | .id'

    The command prints one or more advisory IDs that start with CGA-. If it prints more than one, check each record in the next step.

    If the command prints nothing, Chainguard has no advisory for that ID. That doesn’t mean the package is unaffected. Check that the ID is in uppercase, try the vulnerability’s GHSA ID instead, or contact support.

    If you already have output from chainctl images advisories list, note that its ADVISORY column shows a per-package advisory ID that this feed version doesn’t use. The ID that works in the next step is the CGA- ID in the ALIASES column.

  2. Retrieve the advisory record, and show the fixed version and status of the package that your scanner flagged. Use an advisory ID from the previous step:

    curl -s https://advisories.cgr.dev/chainguard/v2/osv/<advisory-id>.json \
      | jq -r --arg pkg "<package-name>" '.affected[]
          | select(.package.name == $pkg)
          | [ .package.purl,
              ([.ranges[].events[].fixed // empty] | first // "none"),
              ([.ecosystem_specific.components[].latest_event_status] | unique | join(",")) ]
          | @tsv' \
      | sort -u

    Each line shows the package URL, the fixed version, and the advisory status. The arch value in the package URL shows the architecture. Wolfi packages appear twice for each architecture, once with wolfi and once with chainguard in the package URL, with the same fixed version. The fixed version is one of the following:

    • A version string: the package is fixed in that version.
    • 0: Chainguard determined that the package isn’t affected.
    • none: the package is still affected. The status shows why, such as detection while the advisory is under investigation, or pending_upstream_fix while Chainguard waits for an upstream fix.

Contact support

If the finding remains after you work through these checks, contact support. Include the following information:

  • The image reference with its digest, and the platform that you scanned.
  • The scanner’s name and version, and when its database was built.
  • The CVE ID and the Chainguard advisory ID.
  • The flagged package’s name and installed version, and the fixed version that the scanner reports.
  • The scanner output for the finding.

Last updated: 2026-10-01 15:19