hashicorp/packer · error
marshal canonical attestation payload: %w
Error message
marshal canonical attestation payload: %w
What it means
For signed attestations, the statement is first serialized into its canonical JSON form via internalattestation.MarshalPayload. A marshal failure is wrapped as `marshal canonical attestation payload: %w`. Canonicalization enforces strict JSON encoding (sorted keys, no extra whitespace), so it fails on values standard MarshalIndent might tolerate.
Source
Thrown at post-processor/provenance/post-processor.go:308
}
ui.Say(fmt.Sprintf("Wrote attestation to %s", outputPath))
return nil
}
backendConfig, err := p.signingBackendConfig()
if err != nil {
return err
}
signer, verifier, err := p.signingResources(ctx, backendConfig)
if err != nil {
return err
}
payload, err := internalattestation.MarshalPayload(statement)
if err != nil {
return fmt.Errorf("marshal canonical attestation payload: %w", err)
}
bundlePath := sigstoreBundleOutputPath(outputPath)
bundleJSON := []byte(nil)
var envelope internalattestation.Envelope
if backendConfig.Mode == internalattestation.SigningModeKeyless {
envelope, bundleJSON, err = buildSigstoreBundleForSigner(ctx, signer, backendConfig, internalattestation.InTotoPayloadType, payload)
if err != nil {
return fmt.Errorf("sign attestation with Sigstore bundle: %w", err)
}
} else {
signature, signErr := signer.Sign(ctx, internalattestation.InTotoPayloadType, payload)
if signErr != nil {
return fmt.Errorf("sign attestation: %w", signErr)
}
envelope = internalattestation.NewEnvelope(internalattestation.InTotoPayloadType, payload, signature)
}
View on GitHub (pinned to eb36e3c3e4)
Solutions
- Read the wrapped error to identify the un-marshalable value.
- Sanitize or remove non-finite/non-JSON values from the statement.
- Ensure the SBOM source emits valid JSON-compatible data.
- Report to the provenance plugin maintainers if it occurs with stock builder data.
Defensive patterns
Strategy: try-catch
Validate before calling
// canonical round-trip check before signing
if b, err := json.Marshal(statement); err != nil {
return fmt.Errorf("statement not canonicalizable: %w", err)
} else { _ = b } Type guard
func isCanonicalizable(v interface{}) bool {
_, err := json.Marshal(v)
return err == nil
} Try / catch
if err := pp.PostProcess(ctx, ui, artifact); err != nil {
if strings.Contains(err.Error(), "marshal canonical attestation payload") {
// drop signing_mode or fix non-JSON-safe statement values
}
} Prevention
- Keep statement fields finite and JSON-compatible.
- Validate SBOM tool output before feeding it to provenance.
When it happens
Trigger: writeAttestation called with a signing mode other than `none`, where the statement contains values that cannot be canonically encoded (NaN/Inf floats, cycles, unsupported types).
Common situations: SBOM data with non-finite numbers; plugin changes injecting non-JSON-safe fields into the statement before signing.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- signing_mode %q does not support Sigstore bundle emission
- signing_mode %q requires signer
- sign payload: %w
- decode attestation envelope %q: %w
- decode attestation statement: %w
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/964e8c722e78bc98.
Report an issue: GitHub.