hashicorp/packer · error

failed to interpolate `max_retries`: %s

Error message

failed to interpolate `max_retries`: %s

What it means

The template sets `max_retries` on a provisioner with a value containing template variables (e.g. `{{env `RETRIES`}}`), and interpolate.Render failed to evaluate it against the core context — usually because the referenced variable/function is unknown or the expression is malformed. Packer aborts building the provisioner.

Source

Thrown at packer/core.go:296

		}
	}
	// If we're pausing, we wrap the provisioner in a special pauser.
	if rawP.PauseBefore != 0 {
		provisioner = &PausedProvisioner{
			PauseBefore: rawP.PauseBefore,
			Provisioner: provisioner,
		}
	} else if rawP.Timeout != 0 {
		provisioner = &TimeoutProvisioner{
			Timeout:     rawP.Timeout,
			Provisioner: provisioner,
		}
	}
	maxRetries := 0
	if rawP.MaxRetries != "" {
		renderedMaxRetries, err := interpolate.Render(rawP.MaxRetries, c.Context())
		if err != nil {
			return cbp, fmt.Errorf("failed to interpolate `max_retries`: %s", err.Error())
		}
		maxRetries, err = strconv.Atoi(renderedMaxRetries)
		if err != nil {
			return cbp, fmt.Errorf("`max_retries` must be a valid integer: %s", err.Error())
		}
	}
	if maxRetries != 0 {
		provisioner = &RetriedProvisioner{
			MaxRetries:  maxRetries,
			Provisioner: provisioner,
		}
	}

	if rawP.Type == "hcp-sbom" {
		provisioner = &SBOMInternalProvisioner{
			Provisioner: provisioner,
		}
	}

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Set the environment/user variables referenced in `max_retries` before running the build (e.g. export MAX_RETRIES=3).
  2. Use `-var`/`-var-file` to supply any missing user variables.
  3. Fix interpolation syntax typos in the max_retries value.
  4. Give `max_retries` a literal integer if interpolation is not needed.

Example fix

// before
"max_retries": "{{env `RETRIES`}}"   # RETRIES unset -> render fails
// after
$ export RETRIES=3
// or
"max_retries": "3"
Defensive patterns

Strategy: validation

Validate before calling

// Ensure interpolated inputs exist before building (shell):
: "${RETRIES:?RETRIES must be set}"   # fails fast if unset
// HCL2: add validation
variable "retries" {
  type    = string
  default = "0"
  validation { condition = can(tonumber(var.retries)); error_message = "retries must be numeric" }
}

Prevention

When it happens

Trigger: generateCoreBuildProvisionerWithProvisioner calls interpolate.Render(rawP.MaxRetries, c.Context()) when rawP.MaxRetries != "" and Render returns an error: unknown engine variable, missing env var, or invalid template syntax inside the max_retries value.

Common situations: Using `{{env `MAX_RETRIES`}}` while the environment variable is not set; referencing a variable that does not exist in a JSON template; HCL2 variables used in a context where they are not defined; typo in function name inside the interpolation.

Related errors


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