hashicorp/packer · error

required variable not set: %s

Error message

required variable not set: %s

What it means

Packer variables declared with `required = true` (JSON templates) must be supplied by the caller via `-var`, `-var-file`, or environment-injected values. During `Core.validate()` (called from `initialize`), every template variable flagged Required is looked up in the `c.variables` map populated from the CLI/var-files; any missing key is appended to a multierror with this message. The build never starts until all required variables are provided.

Source

Thrown at packer/core.go:887

		if err != nil {
			return fmt.Errorf(
				"min_version is invalid: %s", err)
		}

		if versionActual.LessThan(versionMin) {
			return fmt.Errorf(
				"This template requires Packer version %s or higher; using %s",
				versionMin,
				versionActual)
		}
	}

	// Validate variables are set
	var err error
	for n, v := range c.Template.Variables {
		if v.Required {
			if _, ok := c.variables[n]; !ok {
				err = multierror.Append(err, fmt.Errorf(
					"required variable not set: %s", n))
			}
		}
	}

	// TODO: validate all builders exist
	// TODO: ^^ provisioner
	// TODO: ^^ post-processor

	return err
}

func isDoneInterpolating(v string) (bool, error) {
	// Check for whether the var contains any more references to `user`, wrapped
	// in interpolation syntax.
	filter := `{{\s*user\s*\x60.*\x60\s*}}`
	matched, err := regexp.MatchString(filter, v)
	if err != nil {

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Pass the missing variable explicitly: `packer build -var 'name=value' template.pkr.hcl` (the error lists each missing name).
  2. Create a var-file with the required values and pass `-var-file=vars.pkrvars.hcl` (or place `auto/*.auto.pkrvars.hcl` for auto-loading).
  3. If the variable should be optional, give it a `default` in the template instead of `required: true`.
  4. Check that CI exports the expected environment variables or that your `-var "key=${ENV}"` shell expansion is non-empty.

Example fix

// before
$ packer build template.json
// required variable not set: aws_region
// after
$ packer build -var 'aws_region=us-east-1' -var-file=prodvars.json template.json
Defensive patterns

Strategy: validation

Validate before calling

// check required vars before invoking packer
required := []string{"aws_region", "ami_name_prefix"}
for _, r := range required {
    if os.Getenv(r) == "" {
        panic("missing required variable: " + r)
    }
}

Try / catch

// Go: inspect the multierror for missing-variable entries
if err := core.Initialize(); err != nil {
    if merr, ok := err.(*multierror.Error); ok {
        for _, e := range merr.Errors {
            if strings.HasPrefix(e.Error(), "required variable not set:") {
                log.Printf("supply -var for: %s", e)
            }
        }
    }
    return err
}

Prevention

When it happens

Trigger: A JSON template contains `{"variables": {"ami_name_prefix": {"required": true}}}` (or the SDK marks a variable required) and `packer build`/`validate` runs without that key present in `c.variables` (no `-var 'key=...'`, no `-var-file`, no default), so the `_, ok := c.variables[n]` lookup fails for each missing key.

Common situations: Forgetting `-var` on the command line; a var-file path typo or empty var-file; relying on an env var that isn't actually exported in CI; running `packer validate` without the variables you normally pass to `packer build`; shell var expansion (`${VAR}`) evaluating to empty before reaching Packer.

Related errors


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