Open-Source Wikis

/

Grype

/

How to contribute

/

Debugging

anchore/grype

Debugging

Strategies for diagnosing issues in Grype, both locally and in user-reported bugs.

Log levels

Grype uses internal/log (a thin wrapper over anchore/go-logger). Levels supported:

  • trace — per-package matcher decisions, every vulnerability considered, ignore-rule evaluation.
  • debug — DB load details, dropped matches, ignore counts.
  • info (default) — high-level scan summary.
  • warn — recoverable problems (matcher errors, distro detection failures, EOL distros).
  • error — fatal problems.

Set via flag (-v/-vv) or env var:

GRYPE_LOG_LEVEL=trace grype alpine:latest

Useful debug outputs

  • Why was a match ignored? Run with --show-suppressed. Suppressed matches are kept in the JSON output and rendered with their reason.
  • Why didn't a match show up? --by-cve rewrites IDs to their CVE form, which often clarifies why a vendor-specific record didn't match. Combine with -vv to see ignore-rule evaluation traces.
  • What did the DB say? grype db search vuln <CVE> and grype db search package <name> query the local DB without doing a full scan. Implementation: cmd/grype/cli/commands/db_search*.go.

The explain subcommand

grype alpine:latest -o json | grype explain

Reads a Grype JSON report and produces a human-readable explanation per vulnerability — useful when triaging large reports. Implementation in cmd/grype/cli/commands/explain.go and grype/presenter/explain/.

Profiling

The CLI accepts --profile to write a CPU profile (configured via pkg/profile). Combine with go tool pprof to investigate slow scans.

grype --profile <target>
go tool pprof default.pgo.cpu.pprof

Common failure modes

"no DB found"

unable to load DB: ...

Causes:

  • Network failure during DB download. Retry, or run grype db update manually.
  • Corrupt cache. grype db delete then re-run.
  • Schema mismatch. The CLI only supports ModelVersion=6. If the curator returns an older listing, upgrade Grype.

"unable to determine distro type"

The package context contains a linux.Release, but grype/distro/distro.go::TypeFromRelease could not classify it. Grype logs a warning and continues with non-distro matchers. To suppress, ensure /etc/os-release is present and well-formed in your image.

Matcher panic

callMatcherSafely (grype/vulnerability_matcher.go) wraps each matcher with recover() and returns match.NewFatalError. If you see XYZ encountered a fatal error, the panic stack is logged at debug level. The scan aborts; matchers must not panic.

Spurious matches

Causes, in order of likelihood:

  1. CPE match (NVD) that doesn't account for the distro patch level. Mitigation: distro matchers run first and produce ExactDirectMatch records that supersede ExactIndirectMatch from the stock matcher.
  2. Upstream/source package match that legitimately doesn't apply to the binary package. Mitigation: hard-coded explicit ignores (grype/match/explicit_ignores.go) or user-provided IgnoreRule.
  3. VEX-suppressible match. Provide an OpenVEX or CSAF document and pass --vex.

EOL distro warnings

When --alerts.enable-eol-distro-warnings is set, Grype warns about packages from end-of-life distros. The check is implemented in vulnerability_matcher.go::eolTracker using the optional vulnerability.EOLChecker interface on the provider.

Reading the data race detector

task integration runs a real alpine:latest scan with -race. If you introduce a goroutine bug, the integration job will fail with the data-race report. Look at the offending goroutine pair and trace back to either the matcher (which should be stateless per package) or the partybus.Bus event handlers in cmd/grype/cli/ui/.

Bisecting matcher behavior

If a vulnerability disappears between two Grype releases:

  1. Run both versions against the same target with --no-db-auto-update and an identical local DB.
  2. Use --by-cve on both to normalize advisory IDs.
  3. Look at --show-suppressed to see if the match moved into the ignored set.
  4. If still missing, add -vv and look for the matcher-level decision.

Trace-level matcher decisions

-vv (or GRYPE_LOG_LEVEL=trace) enables log.Trace calls which include lines like:

matcher returned error: ...
ignore filter index remaining filters: N
ignoring N matches due to user-provided ignore rules

These come from grype/vulnerability_matcher.go and grype/match/ignore.go.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Debugging – Grype wiki | Factory