Skip to content

fix: surface the original analysis error instead of context cancellation - #5

Closed
DmitriyLewen wants to merge 2 commits into
mainfrom
fix-shown-429-error
Closed

fix: surface the original analysis error instead of context cancellation#5
DmitriyLewen wants to merge 2 commits into
mainfrom
fix-shown-429-error

Conversation

@DmitriyLewen

@DmitriyLewen DmitriyLewen commented Jun 4, 2026

Copy link
Copy Markdown
Owner

Description

When an analyzer fails with a fatal error during artifact analysis, the user could see a generic context canceled instead of the real cause.

Artifact.Inspect / inspectLayer / VM Analyze run file analysis through errgroup.WithContext. The synchronous file walk uses the group's egCtx for limit.Acquire. When one analysis goroutine returns an error, errgroup cancels egCtx; the still-running walk then fails its next Acquire with context.Canceled, and that walk error was returned before eg.Wait() — which is where the original error actually lives.

This regression was latent since the sync.WaitGrouperrgroup.WithContext migration (aquasecurity#9538) and became observable once aquasecurity#10693 made the Maven pom analyzer return a *types.UserError on a remote 429 Too Many Requests. It only reproduces on large/multi-module trees (e.g. Keycloak), where the walk is still in progress when the 429 fires — a single-pom.xml project surfaces the 429 correctly because the walk finishes first.

The fix: always wait for the analysis goroutines first so eg.Wait() surfaces the original error, and only fall back to the walk error when the goroutines finished cleanly. Applied consistently to the local (fs), image and vm artifacts.

Note: in the masking scenario the user now sees analyze error: <real cause> instead of ... semaphore acquire: context canceled. This is the intended change; no code depends on the old error text.

Reproduced by scanning the Keycloak repository (186 pom.xml files) with an empty ~/.m2 while Maven Central rate-limits the IP.

Before

$ trivy fs --scanners vuln .
2026-06-04T14:53:48+03:00	INFO	[vuln] Vulnerability scanning is enabled
2026-06-04T14:53:49+03:00	FATAL	Fatal error	run error: fs scan error: scan error: scan failed: failed analysis: analyze with traversal: walk dir error: unknown error with adapters/saml/wildfly/wildfly-subsystem/pom.xml: failed to analyze file: analyze file (adapters/saml/wildfly/wildfly-subsystem/pom.xml): semaphore acquire: context canceled

The actual 429 is invisible; the user only sees context canceled, and the reported file is arbitrary (depends on timing).

After

$ trivy fs --scanners vuln .
2026-06-04T14:53:49+03:00	INFO	[vuln] Vulnerability scanning is enabled
2026-06-04T14:53:50+03:00	FATAL	Error	remote Maven repository returned 429 Too Many Requests for https://repo.maven.apache.org/maven2/org/infinispan/infinispan-bom/16.0.8/infinispan-bom-16.0.8.pom. Retry-After: 694.
The repository blocks all subsequent requests from this IP until the block clears.
To avoid this, populate the local Maven cache before scanning (e.g. run `mvn dependency:resolve` and cache ~/.m2 in CI).

Related issues

Related PRs

Checklist

  • I've read the guidelines for contributing to this repository.
  • I've followed the conventions in the PR title.
  • I've added tests that prove my fix is effective or that my feature works.
  • I've updated the documentation with the relevant information (if needed).
  • I've added usage information (if the PR introduces new options)
  • I've included a "before" and "after" example to the description (if the PR is a user interface change).

…ncellation

`errgroup.WithContext` cancels egCtx as soon as one analysis goroutine
returns an error. The synchronous file walk uses the same egCtx for
`limit.Acquire`, so after the cancellation the walk fails with
`context.Canceled`, and that error was returned before `eg.Wait()`. As a
result the real cause - e.g. a remote Maven repository returning
429 Too Many Requests, surfaced as a *types.UserError by aquasecurity#10693 - was
masked by a generic "context canceled" on large trees where the walk is
still running when the cancellation fires.

Wait for the analysis goroutines first so `eg.Wait()` surfaces the
original error, and only fall back to the walk error when the goroutines
finished without error. Applied to the local (fs), image and vm
artifacts, which all share this pattern introduced in aquasecurity#9538.
Verify that Inspect surfaces a fatal analyzer error (*types.UserError,
e.g. a remote Maven 429) instead of the context.Canceled the file walk
hits after errgroup cancels egCtx. Regression test for aquasecurity#10790.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(java): Maven 429 rate limit is reported as semaphore acquire: context canceled instead of the real error

1 participant