hashicorp/packer · warning
Unable to marshal JSON %s
Error message
Unable to marshal JSON %s
What it means
Before writing the manifest, json.MarshalIndent converts the ManifestFile struct to pretty-printed JSON. If marshaling fails, this error is returned. Marshal only fails if the struct contains unsupported values (e.g. channels, funcs, cycles), which in practice indicates a plugin/SDK-level bug or a custom artifact exposing unsupported data rather than a user configuration mistake.
Source
Thrown at post-processor/manifest/post-processor.go:173
}
// If -force is set and we are not on same run, truncate the file. Otherwise
// we will continue to add new builds to the existing manifest file.
if p.config.PackerForce && os.Getenv("PACKER_RUN_UUID") != manifestFile.LastRunUUID {
manifestFile = &ManifestFile{}
}
// Add the current artifact to the manifest file
manifestFile.Builds = append(manifestFile.Builds, *artifact)
manifestFile.LastRunUUID = os.Getenv("PACKER_RUN_UUID")
// Write JSON to disk
if out, err := json.MarshalIndent(manifestFile, "", " "); err == nil {
if err = os.WriteFile(p.config.OutputPath, out, 0664); err != nil {
return source, true, true, fmt.Errorf("Unable to write %s: %s", p.config.OutputPath, err)
}
} else {
return source, true, true, fmt.Errorf("Unable to marshal JSON %s", err)
}
// The manifest should never delete the artifacts it is set to record, so it
// forcibly sets "keep" to true.
return source, true, true, nil
}
func createInterpolatedCustomData(config *Config, customData string) (string, error) {
interpolatedCmd, err := interpolate.Render(customData, &config.ctx)
if err != nil {
return "", fmt.Errorf("Error interpolating custom data: %s", err)
}
return interpolatedCmd, nil
}
View on GitHub (pinned to eb36e3c3e4)
Solutions
- Identify which plugin produced the artifact and check for updates — this usually indicates a plugin bug.
- Report the issue to the custom builder/post-processor plugin maintainer with the full error text.
- Try a released, official builder to confirm the manifest post-processor itself is fine.
- Pin compatible versions of packer and the plugin (packer init / required_plugins) to rule out SDK drift.
Example fix
// before (custom builder returns func in State)
func (a *Artifact) State(id string) interface{} { return map[string]interface{}{"fn": a.closeFn} }
// after
func (a *Artifact) State(id string) interface{} { return map[string]interface{}{"id": a.id} } Defensive patterns
Strategy: try-catch
Try / catch
// JSON-encode artifact state in plugin code before it reaches the manifest
if data, err := json.Marshal(artifactState); err != nil {
log.Printf("artifact state not serializable: %v", err)
} Prevention
- Keep only JSON-serializable values in custom artifact State() maps.
- Test custom builders with the manifest post-processor attached.
- Keep packer and plugins version-compatible via required_plugins.
- Report marshal failures with full output to the plugin maintainer.
When it happens
Trigger: json.MarshalIndent(manifestFile, "", " ") returns an error — an artifact's builder data/state or post-processor fields contain a value JSON cannot encode (func, channel, cycle), typically via custom artifact implementations.
Common situations: Rare; seen with custom/third-party builder plugins whose artifact State() returns non-JSON-serializable values, or SDK version mismatches introducing unsupported fields.
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
- Unable to parse content from %s: %s
- marshal artifact identity: %w
- Unable to open %s for reading: %s
- Unable to write %s: %s
- Error interpolating custom data: %s
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/0202176a3af82b4d.
Report an issue: GitHub.