hashicorp/packer · error

Unable to parse content from %s: %s

Error message

Unable to parse content from %s: %s

What it means

After reading the manifest file, the post-processor unmarshals its JSON into a ManifestFile struct. If the existing packer-manifest.json contains invalid or unexpected JSON, json.Unmarshal fails and PostProcess aborts with this error. This guards against a corrupted or hand-broken manifest.

Source

Thrown at post-processor/manifest/post-processor.go:153

		_, err = os.OpenFile(lockFilename, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
		if err == nil {
			break
		}
		log.Printf("Error locking manifest file for reading and writing. Will sleep and retry. %s", err)
	}
	defer os.Remove(lockFilename)

	// Read the current manifest file from disk
	var contents []byte
	if contents, err = os.ReadFile(p.config.OutputPath); err != nil && !os.IsNotExist(err) {
		return source, true, true, fmt.Errorf("Unable to open %s for reading: %s", p.config.OutputPath, err)
	}

	// Parse the manifest file JSON, if we have one
	manifestFile := &ManifestFile{}
	if len(contents) > 0 {
		if err = json.Unmarshal(contents, manifestFile); err != nil {
			return source, true, true, fmt.Errorf("Unable to parse content from %s: %s", p.config.OutputPath, err)
		}
	}

	// 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)
		}

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Delete or rename the corrupt packer-manifest.json and re-run; a fresh one is created automatically.
  2. Validate the file with `jq . packer-manifest.json` to see the exact syntax error if you want to repair it by hand.
  3. Point output_path at a dedicated file to avoid collisions with other tools' output.
  4. Avoid killing packer mid-post-process; let the manifest write complete.

Example fix

// before: hand-edited manifest with trailing comma
{"builds": [{...},], "last_run_uuid": "..."}
// after: restore valid JSON or remove the file
rm packer-manifest.json && packer build template.pkr.hcl
Defensive patterns

Strategy: fallback

Validate before calling

# detect a corrupt manifest before building
jq -e . packer-manifest.json > /dev/null 2>&1 || { echo 'corrupt manifest, removing'; rm -f packer-manifest.json; }

Type guard

function isParsableManifest(path) {
  try { JSON.parse(fs.readFileSync(path, 'utf8')); return true } catch { return false }
}

Try / catch

// wrapper around packer run
try {
  execSync('packer build template.pkr.hcl')
} catch (e) {
  if (/Unable to parse content from/.test(e.message)) {
    fs.rmSync('packer-manifest.json');
    execSync('packer build template.pkr.hcl'); // regenerate
  } else throw e;
}

Prevention

When it happens

Trigger: json.Unmarshal(contents, manifestFile) returns an error — the existing output file is truncated, manually edited into invalid JSON, contains a different JSON schema (e.g. another tool's output written to the same path), or has a UTF-8/BOM issue.

Common situations: A previous run was killed mid-write leaving a truncated manifest; a user hand-edited packer-manifest.json and broke the syntax; output_path collides with another tool's JSON file.

Understand the failure class

Related errors


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