hashicorp/packer · error

attestation does not contain expected source URI %q

Error message

attestation does not contain expected source URI %q

What it means

When the policy sets SourceURI, verifyPolicy scans predicate.buildDefinition.resolvedDependencies for a dependency whose URI equals the policy value. This error means no resolved dependency in the provenance matches the expected source URI.

Source

Thrown at internal/attestation/verify.go:268

		}
		if err := json.Unmarshal(payload, &typedStatement); err != nil {
			return nil, fmt.Errorf("decode SLSA predicate for policy verification: %w", err)
		}

		if policy.BuilderID != "" && typedStatement.Predicate.RunDetails.Builder.ID != policy.BuilderID {
			return nil, fmt.Errorf("attestation builder id %q does not match expected %q", typedStatement.Predicate.RunDetails.Builder.ID, policy.BuilderID)
		}

		if policy.SourceURI != "" {
			matched := false
			for _, dependency := range typedStatement.Predicate.BuildDefinition.ResolvedDependencies {
				if dependency.URI == policy.SourceURI {
					matched = true
					break
				}
			}
			if !matched {
				return nil, fmt.Errorf("attestation does not contain expected source URI %q", policy.SourceURI)
			}
		}
	}

	return &statement, nil
}

func requiresSigstoreBundle(policy VerificationPolicy) bool {
	return policy.RequireTransparencyLog || policy.RequireObserverTimestamp
}

func verifySigstoreBundleEvidenceImpl(envelope Envelope, cfg BackendConfig, policy VerificationPolicy) error {
	if strings.TrimSpace(policy.SigstoreBundlePath) == "" {
		return fmt.Errorf("bundle-based Rekor or timestamp verification requires -bundle")
	}

	if normalizeVerificationMode(cfg, envelope) != SigningModeKeyless && !envelopeHasCertificate(envelope) {
		return fmt.Errorf("bundle-based Rekor or timestamp verification currently requires a keyless attestation")

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Inspect resolvedDependencies in the attestation and copy the exact dependency URI into policy.SourceURI.
  2. Rebuild the artifact from the expected source revision so the provenance records the required URI.
  3. Relax or remove policy.SourceURI if exact source pinning is not required.
  4. Normalize URI format (scheme, ref vs digest) on both the producer and policy sides so they match byte-for-byte.

Example fix

// before
policy.SourceURI = "https://github.com/org/repo" // attestation lists git+https://...@refs/tags/v1.0.0
// after
policy.SourceURI = "git+https://github.com/org/repo@refs/tags/v1.0.0"
Defensive patterns

Strategy: validation

Validate before calling

var s struct {
	Predicate struct {
		BuildDefinition struct {
			ResolvedDependencies []struct{ URI string `json:"uri"` } `json:"resolvedDependencies"`
		} `json:"buildDefinition"`
	} `json:"predicate"`
}
_ = json.Unmarshal(payload, &s)
for _, d := range s.Predicate.BuildDefinition.ResolvedDependencies {
	if d.URI == policy.SourceURI { return nil }
}
return fmt.Errorf("source URI %q absent from provenance", policy.SourceURI)

Try / catch

_, err := VerifyAttestationFile(path, policy)
if err != nil && strings.Contains(err.Error(), "expected source URI") {
	// inspect resolvedDependencies; align URI scheme/ref format or rebuild from pinned source
}

Prevention

When it happens

Trigger: VerifyAttestationFile with policy.SourceURI set on a provenance attestation whose resolvedDependencies list omits that URI or uses a different URI form (tag vs digest, different scheme, no git+ prefix).

Common situations: Pinning SourceURI to a branch ref while the build recorded the exact commit SHA; missing the git+ scheme prefix (e.g. "git+https://github.com/org/repo@refs/tags/v1.0.0"); attestations built from a fork or mirror with a different repository URI.

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/337c4174c9254c98. Report an issue: GitHub.