hashicorp/packer · error
unexpected attestation statement type %q
Error message
unexpected attestation statement type %q
What it means
verifyPolicy decodes an in-toto attestation payload and requires the top-level statement `_type` to equal the canonical in-toto statement type (internalprovenance.StatementType, e.g. "https://in-toto.io/Statement/v1"). This error means the payload parsed as JSON but its `_type` field is missing or set to an unexpected value, so it is not a valid in-toto statement for verification.
Source
Thrown at internal/attestation/verify.go:227
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 {
return nil, fmt.Errorf("builder and source policy checks require predicate type %q, got %q", internalprovenance.SLSAProvenanceV1PredicateType, statement.PredicateType)
}
var typedStatement struct {View on GitHub (pinned to eb36e3c3e4)
Solutions
- Open the attestation file and check the top-level `_type` field; ensure it is the expected in-toto statement URI (https://in-toto.io/Statement/v1).
- Regenerate the attestation with a current version of the producing tool so it emits a v1 in-toto statement.
- Verify you are passing the extracted statement, not a DSSE envelope or bundle file, to verification.
- If a custom predicate type is used, confirm only the predicateType differs and the `_type` remains the standard statement type.
Example fix
// before
{"_type":"https://in-toto.io/Statement/v0.1","predicateType":"https://slsa.dev/provenance/v1",...}
// after
{"_type":"https://in-toto.io/Statement/v1","predicateType":"https://slsa.dev/provenance/v1",...} Defensive patterns
Strategy: validation
Validate before calling
var s struct{ Type string `json:"_type"` }
if err := json.Unmarshal(payload, &s); err != nil || s.Type != "https://in-toto.io/Statement/v1" {
return fmt.Errorf("not an in-toto v1 statement: type=%q", s.Type)
} Type guard
func isInTotoStatement(payload []byte) bool {
var s struct{ Type string `json:"_type"` }
return json.Unmarshal(payload, &s) == nil && s.Type == "https://in-toto.io/Statement/v1"
} Try / catch
stmt, err := VerifyAttestationFile(path, policy)
if err != nil {
var decodeErr *json.UnmarshalTypeError
if errors.As(err, &decodeErr) || strings.Contains(err.Error(), "unexpected attestation statement type") {
// wrong file format: check you extracted the statement, not the envelope
}
return err
} Prevention
- Always feed the extracted in-toto statement (not the DSSE envelope or bundle) to verification
- Check _type in the attestation file before running policy checks
- Pin the producing tool's version so statement format (v1) is stable
When it happens
Trigger: Calling VerifyAttestationFile (which calls verifyPolicy) with an attestation file whose `_type` is empty, an older in-toto version (e.g. Statement/v0.1), or a non-statement JSON document.
Common situations: Pointing the attestation policy at a raw Sigstore bundle, DSSE envelope, or SBOM/scan report instead of an extracted in-toto statement; attestations generated by older tooling that used v0.1 statements; hand-written or truncated JSON files.
Related errors
- attestation %q has unexpected payloadType %q (want %q)
- attestation envelope has no signatures
- The `bucket_name` must be specified
- `channel` is currently a required field.
- the `bucket_name` must be specified
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/635dad9255af2c52.
Report an issue: GitHub.