hashicorp/packer · error
marshal attestation payload: %w
Error message
marshal attestation payload: %w
What it means
writeAttestation serializes the in-toto statement with json.MarshalIndent when signing mode is `none` (unsigned output). A failure marshaling the statement struct is wrapped as `marshal attestation payload: %w`. This is rare because the statement is a plain Go struct, but non-marshalable fields (channels, funcs, NaN floats) or corrupted internal state trigger it.
Source
Thrown at post-processor/provenance/post-processor.go:285
predicate, predicateType, err := buildSBOMPredicate(rawSBOM, format)
if err != nil {
return err
}
statement := internalprovenance.WrapInToto(subjects, predicateType, predicate)
if err := p.writeAttestation(ctx, ui, statement, paths.SBOMAttestation); err != nil {
return err
}
ui.Say(fmt.Sprintf("Wrote SBOM to %s", paths.SBOMRaw))
return nil
}
func (p *PostProcessor) writeAttestation(ctx context.Context, ui packersdk.Ui, statement interface{}, outputPath string) error {
if p.config.SigningMode == internalattestation.SigningModeNone {
payload, err := json.MarshalIndent(statement, "", " ")
if err != nil {
return fmt.Errorf("marshal attestation payload: %w", err)
}
if err := atomicWriteFile(outputPath, payload, 0664); err != nil {
return fmt.Errorf("write attestation %q: %w", outputPath, err)
}
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 errView on GitHub (pinned to eb36e3c3e4)
Solutions
- Inspect the wrapped json error after the colon; it names the offending type/value.
- Sanitize numeric fields (replace NaN/Inf) before building the statement.
- Check for recent changes to the statement struct that introduced non-serializable fields.
- File an issue if the statement comes purely from built-in builder data, as it should always marshal.
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure statement values are JSON-safe before calling PostProcess
if _, err := json.Marshal(statement); err != nil {
return fmt.Errorf("statement not JSON-serializable: %w", err)
} Type guard
func isJSONSafe(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 attestation payload") {
// inspect statement fields for NaN/Inf or non-JSON types
}
} Prevention
- Sanitize external SBOM data for NaN/Inf numbers.
- Keep statement structs JSON-serializable.
- Pin plugin versions so statement schemas stay stable.
When it happens
Trigger: PostProcess or writeSBOMAttestation hands writeAttestation a statement containing a value json.MarshalIndent cannot encode (e.g. a NaN/Inf number produced by SBOM tooling output, or an unsupported type injected via custom data).
Common situations: Feeding SBOM/provenance data parsed from an external tool where numeric fields contain NaN or the statement carries non-JSON types.
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
- marshal artifact identity: %w
- marshal signed envelope: %w
- decode attestation envelope %q: %w
- decode attestation statement: %w
- attestation subject does not match artifact %q
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/f0b677965741f3c7.
Report an issue: GitHub.