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

  1. Decode the base64 payload and inspect it with `jq .` to confirm it is an in-toto statement with correct field types
  2. Re-generate the attestation with a matching version of the signing tooling
  3. Check internalprovenance.Statement field tags against the actual payload keys
  4. 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

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


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