hashicorp/packer · error
decode attestation statement: %w
Error message
decode attestation statement: %w
What it means
verifyPolicy wraps the json.Unmarshal failure of the envelope payload into an internalprovenance.Statement as `decode attestation statement: %w`. This runs after signature verification succeeds, so the payload bytes are authentic but not a valid in-toto statement JSON — the structure does not match _type/subject/predicateType/predicate fields or contains type-mismatched values.
Source
Thrown at internal/attestation/verify.go:223
}
return false
}
func isRecognizedKMSReference(value string) bool {
for _, prefix := range []string{"awskms://", "gcpkms://", "azurekms://", "hashivault://"} {
if strings.HasPrefix(value, prefix) {
return true
}
}
return false
}
func verifyPolicy(payload []byte, policy VerificationPolicy) (*internalprovenance.Statement, error) {
var statement internalprovenance.Statement
if err := json.Unmarshal(payload, &statement); err != nil {
return nil, fmt.Errorf("decode attestation statement: %w", err)
}
if statement.Type != internalprovenance.StatementType {
return nil, fmt.Errorf("unexpected attestation statement type %q", statement.Type)
}
if policy.PredicateType != "" && statement.PredicateType != policy.PredicateType {
return nil, fmt.Errorf("attestation predicate type %q does not match expected %q", statement.PredicateType, policy.PredicateType)
}
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 {View on GitHub (pinned to eb36e3c3e4)
Solutions
- Decode the base64 payload and inspect it with `jq .` to confirm it is an in-toto statement with correct field types
- Re-generate the attestation with a matching version of the signing tooling
- Check internalprovenance.Statement field tags against the actual payload keys
- If a policy expects SLSA provenance, confirm predicateType is SLSAProvenanceV1PredicateType so the typed decode path is exercised correctly
Example fix
// before: payload missing _type field
// {"subject":[...],"predicateType":"..."}
// after: emit a full in-toto statement
// {"_type":"https://in-toto.io/Statement/v1","subject":[...],"predicateType":"...","predicate":{...}} Defensive patterns
Strategy: validation
Validate before calling
payload, err := attestation.DecodeEnvelopePayload(envelope)
if err != nil { return err }
var probe struct{ Type string `json:"_type"`; PredicateType string `json:"predicateType"` }
if err := json.Unmarshal(payload, &probe); err != nil || probe.Type == "" {
return fmt.Errorf"payload is not an in-toto statement"%w", err)
} Type guard
func looksLikeStatement(payload []byte) bool {
var s internalprovenance.Statement
return json.Unmarshal(payload, &s) == nil && s.Type == internalprovenance.StatementType
} Try / catch
if _, err := attestation.VerifyAttestationFile(ctx, path, cfg, policy); err != nil {
if strings.Contains(err.Error(), "decode attestation statement") {
return fmt.Errorf"signature is valid but payload is not a recognized statement: %w", err)
}
return err
} Prevention
- Only verify statements produced by the same schema version of this toolchain
- Round-trip a generated statement through json.Unmarshal in tests before signing
- Pin the attestation-producing tool version across signing and verification
- Inspect decoded payloads when migrating between SLSA versions
When it happens
Trigger: An envelope whose decoded payload is not an in-toto Statement (custom payload smuggled past payloadType check is impossible here, but malformed statement JSON is not); statement produced by a different/older schema version with incompatible field types; payload re-encoded with different field names.
Common situations: Upstream tool changed the statement schema; hand-crafted attestations in tests with wrong shapes; truncation or re-serialization of the base64 payload during post-processing; mixing provenance formats (e.g. SLSA v0.1 layout) that don't unmarshal into the Statement struct.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- decode attestation envelope %q: %w
- attestation %q has unexpected payloadType %q (want %q)
- marshal attestation payload: %w
- marshal canonical attestation payload: %w
- failed to retrieve packer release index from %s: %w
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/e15fb70d74d6c3be.
Report an issue: GitHub.