hashicorp/packer · error

Error interpolating custom data: %s

Error message

Error interpolating custom data: %s

What it means

Packer's manifest post-processor renders the `custom_data` field through the HCL2/template interpolation engine before writing the manifest. If the template engine cannot evaluate the string (unknown function, bad placeholder syntax, invalid variables), createInterpolatedCustomData wraps the engine error in `Error interpolating custom data: %s` and PostProcess aborts. The manifest file is not written or is written without the custom_data entry.

Source

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

	// 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. Fix the interpolation syntax in `custom_data` (variables need leading dot and spaces: `{{ .BuildName }}`).
  2. Run `packer validate` on the template to catch bad placeholders before building.
  3. Check the wrapped error text after the colon; it names the exact function or variable that failed.
  4. If a variable is genuinely unavailable at post-process time, remove it or move the data into the builder.

Example fix

// before
custom_data = { id = "{{build_ID}}" }
// after
custom_data = { id = "{{ uuidv4 }}" }
Defensive patterns

Strategy: validation

Validate before calling

// pre-validate custom_data template before the build
err := interpolate.Validate(cfg.CustomData, &ctx)
if err != nil { return fmt.Errorf("invalid custom_data: %w", err) }

Try / catch

// Go: check error from PostProcess and inspect the wrapped interpolation error
if err := pp.PostProcess(ctx, ui, artifact); err != nil {
    if strings.Contains(err.Error(), "Error interpolating custom data") {
        // fall back to plain custom_data or abort with a clear message
    }
}

Prevention

When it happens

Trigger: Running `packer build` with a manifest post-processor whose `custom_data` contains invalid interpolation syntax (e.g. `{{build_ID}}` instead of `{{ .BuildName }}`), a call to a nonexistent template function, or context variables not available in the post-processor phase (e.g. some `{{ .HCLConfig... }}` values).

Common situations: Copy-pasted templates from docs with the wrong placeholder spacing (`{{build_name}}` vs `{{ .BuildName }}`); using builder-only variables in a post-processor; typos in function names like `timestampa`.

Related errors


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