{"record":{"id":"964e8c722e78bc98","repo":"hashicorp/packer","slug":"marshal-canonical-attestation-payload-w","errorCode":null,"errorMessage":"marshal canonical attestation payload: %w","messagePattern":"marshal canonical attestation payload: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"post-processor/provenance/post-processor.go","lineNumber":308,"sourceCode":"\t\t}\n\n\t\tui.Say(fmt.Sprintf(\"Wrote attestation to %s\", outputPath))\n\t\treturn nil\n\t}\n\n\tbackendConfig, err := p.signingBackendConfig()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tsigner, verifier, err := p.signingResources(ctx, backendConfig)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tpayload, err := internalattestation.MarshalPayload(statement)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshal canonical attestation payload: %w\", err)\n\t}\n\n\tbundlePath := sigstoreBundleOutputPath(outputPath)\n\tbundleJSON := []byte(nil)\n\tvar envelope internalattestation.Envelope\n\tif backendConfig.Mode == internalattestation.SigningModeKeyless {\n\t\tenvelope, bundleJSON, err = buildSigstoreBundleForSigner(ctx, signer, backendConfig, internalattestation.InTotoPayloadType, payload)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"sign attestation with Sigstore bundle: %w\", err)\n\t\t}\n\t} else {\n\t\tsignature, signErr := signer.Sign(ctx, internalattestation.InTotoPayloadType, payload)\n\t\tif signErr != nil {\n\t\t\treturn fmt.Errorf(\"sign attestation: %w\", signErr)\n\t\t}\n\t\tenvelope = internalattestation.NewEnvelope(internalattestation.InTotoPayloadType, payload, signature)\n\t}\n","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/post-processor/provenance/post-processor.go#L290-L326","documentation":"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.","triggerScenarios":"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).","commonSituations":"SBOM data with non-finite numbers; plugin changes injecting non-JSON-safe fields into the statement before signing.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// canonical round-trip check before signing\nif b, err := json.Marshal(statement); err != nil {\n    return fmt.Errorf(\"statement not canonicalizable: %w\", err)\n} else { _ = b }","typeGuard":"func isCanonicalizable(v interface{}) bool {\n    _, err := json.Marshal(v)\n    return err == nil\n}","tryCatchPattern":"if err := pp.PostProcess(ctx, ui, artifact); err != nil {\n    if strings.Contains(err.Error(), \"marshal canonical attestation payload\") {\n        // drop signing_mode or fix non-JSON-safe statement values\n    }\n}","preventionTips":["Keep statement fields finite and JSON-compatible.","Validate SBOM tool output before feeding it to provenance."],"tags":["json","canonicalization","attestation","signing"],"backgroundTag":"json-marshal-failed","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}