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

  1. Identify which plugin produced the artifact and check for updates — this usually indicates a plugin bug.
  2. Report the issue to the custom builder/post-processor plugin maintainer with the full error text.
  3. Try a released, official builder to confirm the manifest post-processor itself is fine.
  4. 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

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


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