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

  1. 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).
  2. Regenerate the attestation with a current version of the producing tool so it emits a v1 in-toto statement.
  3. Verify you are passing the extracted statement, not a DSSE envelope or bundle file, to verification.
  4. 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

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


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