Summary
Since 2026-06-09 ~05:30 UTC, every docker scout cves scan of liquibase/liquibase-secure images run in the context of our Docker organization crashes with a nil-pointer panic in internal/vex.GenerateCanonicalID (vex.go:179). The same scan in personal/anonymous context passes. It reproduces with no --vex-location at all and on every CLI version we tested (1.18.4, 1.19.0, 1.20.3, 1.20.4, 1.21.0), and began without any client-side change (same pinned CLI, runner image, base image digest, Dockerfile). Everything points to an exception/VEX document served by the Scout platform for our org that the CLI converts into an empty document and then dereferences.
Stack trace
✓ Loaded 42 VEX documents
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x111b0b1]
github.com/docker/scout-cli-plugin/internal/vex.GenerateCanonicalID({{{0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, 0x0, 0x0, ...}, ...})
internal/vex/vex.go:179 +0x31
github.com/docker/scout-cli-plugin/internal/vex.ApplyVEX({...}, 0xc08dc5cb00, {0xc00083dce0, 0x2b, ...})
internal/vex/vex.go:137 +0x1b8
github.com/docker/scout-cli-plugin/cves.(*Lister).FromSBOM(...)
cves/cves.go:133 +0x708
Reproduction
Requires an account belonging to the affected organization (liquibase), with the org set as the Scout context — the bug does not reproduce in personal context:
docker login # account in the liquibase org
docker scout config organization liquibase
docker pull liquibase/liquibase-secure:latest
docker scout cves liquibase/liquibase-secure:latest \
--format sarif --output out.sarif --only-severity critical,high
# → panic; exit code 2; no SARIF written
Evidence
| Scan (CLI v1.20.3 and v1.21.0) |
Result |
liquibase-secure:latest, org context (org service account) |
PANIC |
liquibase-secure:latest, personal context (no org set) |
PASS |
| same digest re-tagged to a neutral local name, org context |
PANIC |
| locally built image with same content, org context |
PANIC |
liquibase-secure:5.1.1 (older content, pushed 2026-03-26), org context |
PASS |
liquibase/liquibase:latest, alpine, eclipse-temurin, cassandra, neo4j, org context |
PASS |
with/without --vex-location, any local VEX content |
irrelevant — panic persists with zero local VEX files |
Additional data points:
- The slice passed to
ApplyVEX always contains exactly one more document than was loaded from disk (0 files → 1 doc; 42 files → 43 docs, the 0x2b in the trace). The extra document is entirely zero-valued: the panic argument decodes as a zero vex.VEX (go-vex layout — four empty strings, then Timestamp *time.Time = nil). GenerateCanonicalID starts with the equivalent of go-vex CanonicalHash() (doc.Timestamp.Unix()), which faults.
- The extra document is appended in
FromSBOM after LoadVEXs (the attestations.VexDocuments path). The image itself carries only standard buildx SPDX + SLSA provenance attestations; docker scout vex get reports "Found 0 VEX attestations".
- Running with the org configured but an account without team permissions fails gracefully in the same code path with:
could not list CVEs ... Path: [vulnerabilitiesByPackageForImageCoords] (query includes includeExcepted) — i.e., org-scoped exception data is fetched during cves, consistent with the crashing document being an org exception record.
- Our Scout Dashboard shows no exceptions at all (Vulnerabilities → Exceptions: 0 entries, org-wide), so whatever record the backend serves to the CLI is not visible to us and we cannot remove it ourselves.
- Scans passed until 2026-06-08 ~20:30 UTC and failed from 2026-06-09 ~05:30 UTC with no client-side change.
liquibase/liquibase-secure is the only Scout-enrolled repo in our org.
Asks
- CLI hardening: nil-guard
Timestamp (and skip/log empty documents) in GenerateCanonicalID/ApplyVEX instead of segfaulting — go-vex's own SortDocuments already nil-guards this field.
- Platform investigation: what exception/VEX record started being served for the
liquibase org / liquibase/liquibase-secure around 2026-06-09 05:30 UTC, and why does it deserialize to an empty document in the CLI? (Also filed with Docker Support: ticket #____.)
Environment
- scout CLI 1.18.4 / 1.19.0 / 1.20.3 / 1.20.4 / 1.21.0 — all panic (linux/amd64, GitHub Actions ubuntu-22.04; also reproduced via docker/scout-action v1.20.3)
- Docker org:
liquibase; affected repo: liquibase/liquibase-secure (Scout-enrolled)
Summary
Since 2026-06-09 ~05:30 UTC, every
docker scout cvesscan ofliquibase/liquibase-secureimages run in the context of our Docker organization crashes with a nil-pointer panic ininternal/vex.GenerateCanonicalID(vex.go:179). The same scan in personal/anonymous context passes. It reproduces with no--vex-locationat all and on every CLI version we tested (1.18.4, 1.19.0, 1.20.3, 1.20.4, 1.21.0), and began without any client-side change (same pinned CLI, runner image, base image digest, Dockerfile). Everything points to an exception/VEX document served by the Scout platform for our org that the CLI converts into an empty document and then dereferences.Stack trace
Reproduction
Requires an account belonging to the affected organization (
liquibase), with the org set as the Scout context — the bug does not reproduce in personal context:Evidence
liquibase-secure:latest, org context (org service account)liquibase-secure:latest, personal context (no org set)liquibase-secure:5.1.1(older content, pushed 2026-03-26), org contextliquibase/liquibase:latest,alpine,eclipse-temurin,cassandra,neo4j, org context--vex-location, any local VEX contentAdditional data points:
ApplyVEXalways contains exactly one more document than was loaded from disk (0 files → 1 doc; 42 files → 43 docs, the0x2bin the trace). The extra document is entirely zero-valued: the panic argument decodes as a zerovex.VEX(go-vex layout — four empty strings, thenTimestamp *time.Time = nil).GenerateCanonicalIDstarts with the equivalent of go-vexCanonicalHash()(doc.Timestamp.Unix()), which faults.FromSBOMafterLoadVEXs(theattestations.VexDocumentspath). The image itself carries only standard buildx SPDX + SLSA provenance attestations;docker scout vex getreports "Found 0 VEX attestations".could not list CVEs ... Path: [vulnerabilitiesByPackageForImageCoords](query includesincludeExcepted) — i.e., org-scoped exception data is fetched duringcves, consistent with the crashing document being an org exception record.liquibase/liquibase-secureis the only Scout-enrolled repo in our org.Asks
Timestamp(and skip/log empty documents) inGenerateCanonicalID/ApplyVEXinstead of segfaulting — go-vex's ownSortDocumentsalready nil-guards this field.liquibaseorg /liquibase/liquibase-securearound 2026-06-09 05:30 UTC, and why does it deserialize to an empty document in the CLI? (Also filed with Docker Support: ticket #____.)Environment
liquibase; affected repo:liquibase/liquibase-secure(Scout-enrolled)