Describe the bug
Running docker scout cves : against a multi-arch image index (manifest list) with no attestation sidecar panics with a nil pointer dereference in createVCS(). Scout falsely reports ✓ Provenance obtained from attestation before crashing — even though docker buildx imagetools inspect --format '{{ json .Provenance }}' returns blank/null, confirming no provenance exists.
Scanning the exact same image by digest succeeds. The bug is specific to tag-based resolution of multi-arch image indexes with no unknown/unknown attestation entry.
This persists on v1.21.0 despite "Fix VCS provenance parsing" being listed in the v1.20.0+ changelog.
To Reproduce
Use any multi-arch image (manifest list) built without a provenance attestation sidecar — i.e. no unknown/unknown platform entry in the image index.
Fails (tag-based):
docker scout cves registry.example.com/project/nginx:1.0.0
Succeeds (digest-based, same image):
docker scout cves registry.example.com/project/nginx@sha256:
Confirm no attestation is present:
docker buildx imagetools inspect registry.example.com/project/nginx:1.0.0 \
--format '{{ json .Provenance }}'
# returns blank / null output
docker buildx imagetools inspect registry.example.com/project/nginx:1.0.0
# shows only linux/amd64 and linux/arm64 manifests — no unknown/unknown attestation entry
Expected behavior
Scout detects no provenance attestation and skips provenance parsing, completing the CVE scan from the SBOM alone. It should not report ✓ Provenance obtained from attestation when none exists.
Actual behavior
✓ SBOM obtained from attestation, 30 packages found
✓ Provenance obtained from attestation
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x2ee7dde]
goroutine 1 [running]:
github.com/docker/scout-cli-plugin/internal/attestations.createVCS(0x18df7bfb26e0)
/home/runner/work/scout-cli-plugin/scout-cli-plugin/internal/attestations/provenance.go:128 +0x1e
github.com/docker/scout-cli-plugin/internal/attestations.(*Attestations).Provenance(0x18df7c12a900)
/home/runner/work/scout-cli-plugin/scout-cli-plugin/internal/attestations/provenance.go:117 +0xb3
github.com/docker/scout-cli-plugin/internal/attestations.(*Attestations).CombineWith(0x18df7c12a900, 0x18df7b28c700)
/home/runner/work/scout-cli-plugin/scout-cli-plugin/internal/attestations/attestations.go:155 +0x105
github.com/docker/scout-cli-plugin/sbom.(*Service).FromImageAttestation(0x5?, {0x7995ac8?, 0x18df7bd0b500?}, 0x52c899?, ...)
/home/runner/work/scout-cli-plugin/scout-cli-plugin/sbom/sbom.go:270 +0xa5
github.com/docker/scout-cli-plugin/sbom.(*Service).FromImage(...)
/home/runner/work/scout-cli-plugin/scout-cli-plugin/sbom/sbom.go:161 +0x327
github.com/docker/scout-cli-plugin/sbom.(*Service).Get(...)
/home/runner/work/scout-cli-plugin/scout-cli-plugin/sbom/sbom.go:124 +0x597
github.com/docker/scout-cli-plugin/internal/commands/cves.NewCmd.func2(...)
/home/runner/work/scout-cli-plugin/scout-cli-plugin/internal/commands/cves/cves.go:234 +0x7d7
Workarounds
- Scan by digest:
docker scout cves registry.example.com/project/nginx@sha256:
- Skip provenance parsing:
docker scout cves --only-sbom registry.example.com/project/nginx:1.0.0
Root cause hypothesis
When resolving a tag pointing to a multi-arch image index, scout's attestation detection at the index level returns a false positive — it signals provenance was found when the manifest list contains no unknown/unknown attestation sidecar. A nil/empty provenance object is then passed into CombineWith() → Provenance() → createVCS() at provenance.go:128 without a nil guard, causing the panic.
Two issues compound here: (1) false positive attestation detection on manifest lists, and (2) missing nil guard in createVCS(). Both should be fixed independently.
Environment
- Scout version: v1.21.0 (go1.26.3 - linux/amd64)
- Docker CLI: v29.5.0
- OS: Linux amd64
Describe the bug
Running
docker scout cves :against a multi-arch image index (manifest list) with no attestation sidecar panics with a nil pointer dereference increateVCS(). Scout falsely reports✓ Provenance obtained from attestationbefore crashing — even thoughdocker buildx imagetools inspect --format '{{ json .Provenance }}'returns blank/null, confirming no provenance exists.Scanning the exact same image by digest succeeds. The bug is specific to tag-based resolution of multi-arch image indexes with no
unknown/unknownattestation entry.This persists on v1.21.0 despite "Fix VCS provenance parsing" being listed in the v1.20.0+ changelog.
To Reproduce
Use any multi-arch image (manifest list) built without a provenance attestation sidecar — i.e. no
unknown/unknownplatform entry in the image index.Fails (tag-based):
Succeeds (digest-based, same image):
Confirm no attestation is present:
Expected behavior
Scout detects no provenance attestation and skips provenance parsing, completing the CVE scan from the SBOM alone. It should not report
✓ Provenance obtained from attestationwhen none exists.Actual behavior
Workarounds
docker scout cves registry.example.com/project/nginx@sha256:docker scout cves --only-sbom registry.example.com/project/nginx:1.0.0Root cause hypothesis
When resolving a tag pointing to a multi-arch image index, scout's attestation detection at the index level returns a false positive — it signals provenance was found when the manifest list contains no
unknown/unknownattestation sidecar. A nil/empty provenance object is then passed intoCombineWith()→Provenance()→createVCS()atprovenance.go:128without a nil guard, causing the panic.Two issues compound here: (1) false positive attestation detection on manifest lists, and (2) missing nil guard in
createVCS(). Both should be fixed independently.Environment