hashicorp/packer · error
decode SLSA predicate for policy verification: %w
Error message
decode SLSA predicate for policy verification: %w
What it means
After confirming the statement is SLSA provenance v1, verifyPolicy re-decodes the payload into a typed structure that includes the SLSAProvenancePredicate. This error wraps any JSON decoding failure of that typed structure, e.g. when the predicate object is missing, not an object, or its fields (runDetails, buildDefinition) have incompatible shapes.
Source
Thrown at internal/attestation/verify.go:252
if policy.ArtifactPath != "" {
if err := verifyArtifactSubject(statement.Subject, policy.ArtifactPath); err != nil {
return nil, err
}
}
if policy.BuilderID != "" || policy.SourceURI != "" {
if statement.PredicateType != internalprovenance.SLSAProvenanceV1PredicateType {
return nil, fmt.Errorf("builder and source policy checks require predicate type %q, got %q", internalprovenance.SLSAProvenanceV1PredicateType, statement.PredicateType)
}
var typedStatement struct {
Type string `json:"_type"`
Subject []internalprovenance.Subject `json:"subject"`
PredicateType string `json:"predicateType"`
Predicate internalprovenance.SLSAProvenancePredicate `json:"predicate"`
}
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)
}
}View on GitHub (pinned to eb36e3c3e4)
Solutions
- Inspect the attestation's `predicate` field; ensure it exists and follows the SLSA provenance v1 schema (buildDefinition, runDetails).
- Regenerate the attestation with an up-to-date, spec-compliant producer.
- Validate the attestation against the SLSA v1 JSON schema before verification.
- Check the underlying wrapped decode error (%w) for the exact JSON path/type that failed.
Example fix
// before
{"predicateType":"https://slsa.dev/provenance/v1"} // predicate missing
// after
{"predicateType":"https://slsa.dev/provenance/v1","predicate":{"buildDefinition":{...},"runDetails":{...}}} Defensive patterns
Strategy: type-guard
Validate before calling
var s struct {
PredicateType string `json:"predicateType"`
Predicate struct {
RunDetails json.RawMessage `json:"runDetails"`
BuildDefinition json.RawMessage `json:"buildDefinition"`
} `json:"predicate"`
}
if err := json.Unmarshal(payload, &s); err != nil || len(s.Predicate.RunDetails) == 0 {
return fmt.Errorf("malformed SLSA v1 predicate")
} Type guard
func hasSLSAV1PredicateShape(payload []byte) bool {
var s struct {
Predicate struct {
RunDetails json.RawMessage `json:"runDetails"`
BuildDefinition json.RawMessage `json:"buildDefinition"`
} `json:"predicate"`
}
return json.Unmarshal(payload, &s) == nil && s.Predicate.RunDetails != nil && s.Predicate.BuildDefinition != nil
} Try / catch
_, err := VerifyAttestationFile(path, policy)
if err != nil && strings.Contains(err.Error(), "decode SLSA predicate") {
var syntaxErr *json.SyntaxError
if errors.As(err, &syntaxErr) {
log.Printf("bad JSON at offset %d", syntaxErr.Offset)
}
} Prevention
- Validate attestations against the SLSA v1 JSON schema before verification
- Never hand-edit attestation JSON
- Check the wrapped %w error for the failing JSON path
When it happens
Trigger: VerifyAttestationFile with a policy containing BuilderID or SourceURI, on an attestation whose predicateType claims v1 but whose predicate body is absent, null, or does not match the SLSA v1 schema (wrong nesting, wrong field types).
Common situations: Hand-crafted or tool-mangled attestations that label themselves v1 but omit the predicate; predicates following an incompatible draft schema; corrupted/truncated JSON files.
Related errors
- builder and source policy checks require predicate type %q,
- attestation builder id %q does not match expected %q
- attestation does not contain expected source URI %q
- signing_mode %q does not support Sigstore bundle emission
- decode envelope payload: %w
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/3357d2e6e0340472.
Report an issue: GitHub.