hashicorp/packer · error

decode attestation envelope %q: %w

Error message

decode attestation envelope %q: %w

What it means

VerifyAttestationFile wraps the json.Unmarshal failure for the envelope in `decode attestation envelope %q: %w`. It means the file contents are not valid JSON matching the Envelope shape (payload, payloadType, signatures). The raw JSON syntax error from encoding/json is preserved.

Source

Thrown at internal/attestation/verify.go:49

}

var loadSigstoreBundle = sigstorebundle.LoadJSONFromPath

var newSigstoreBundleVerifier = sigstoreverify.NewVerifier

var verifySigstoreBundleEvidence = func(envelope Envelope, cfg BackendConfig, policy VerificationPolicy) error {
	return verifySigstoreBundleEvidenceImpl(envelope, cfg, policy)
}

func VerifyAttestationFile(ctx context.Context, path string, cfg BackendConfig, policy VerificationPolicy) (*internalprovenance.Statement, error) {
	contents, err := os.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("read attestation %q: %w", path, err)
	}

	var envelope Envelope
	if err := json.Unmarshal(contents, &envelope); err != nil {
		return nil, fmt.Errorf("decode attestation envelope %q: %w", path, err)
	}

	if envelope.PayloadType != InTotoPayloadType {
		return nil, fmt.Errorf("attestation %q has unexpected payloadType %q (want %q)",
			path, envelope.PayloadType, InTotoPayloadType)
	}

	if err := verifyEnvelopeSignature(ctx, path, cfg, policy, envelope); err != nil {
		return nil, err
	}

	payload, err := DecodeEnvelopePayload(envelope)
	if err != nil {
		return nil, err
	}

	statement, err := verifyPolicy(payload, policy)
	if err != nil {

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Validate the file with `jq . file` or json.Valid to confirm it parses as JSON
  2. Ensure you are passing the DSSE envelope file, not the signed artifact or bundle
  3. Re-download or re-generate the attestation if it was truncated or empty
  4. Check that top-level fields have the right types (payload/payloadType strings, signatures array)

Example fix

// before
stmt, err := attestation.VerifyAttestationFile(ctx, "bin/app", cfg, policy)

// after: verify the envelope file
contents, _ := os.ReadFile("bin/app.attestation.json")
if !json.Valid(contents) { log.Fatal("not valid JSON") }
stmt, err := attestation.VerifyAttestationFile(ctx, "bin/app.attestation.json", cfg, policy)
Defensive patterns

Strategy: validation

Validate before calling

contents, err := os.ReadFile(path)
if err != nil { return err }
if !json.Valid(contents) { return fmt.Errorf"%s is not valid JSON", path) }
var probe struct{ PayloadType string `json:"payloadType"` }
if json.Unmarshal(contents, &probe) != nil || probe.PayloadType == "" { return fmt.Errorf"%s is not a DSSE envelope", path) }

Type guard

func looksLikeEnvelope(b []byte) bool {
    var e attestation.Envelope
    return json.Unmarshal(b, &e) == nil && e.PayloadType != ""
}

Try / catch

if _, err := attestation.VerifyAttestationFile(ctx, path, cfg, policy); err != nil {
    if strings.Contains(err.Error(), "decode attestation envelope") {
        return fmt.Errorf"%s is not a DSSE envelope JSON document", path)
    }
    return err
}

Prevention

When it happens

Trigger: Passing a non-JSON file (binary artifact, empty file, truncated download, HTML error page) to VerifyAttestationFile; passing a JSON file whose top level is an array or has mismatched types (e.g. signatures as a string); file corrupted in transfer.

Common situations: Pointing the verifier at the artifact instead of the .attestation.json sidecar; partial uploads in CI; editing the envelope by hand and breaking JSON syntax; a proxy returning an error page saved as the attestation.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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