hashicorp/packer · error

Error processing command

Error message

Error processing command: %s

What it means

The shell provisioner renders the user-supplied `execute_command` HCL/Go template (with generated data like .Path, .Vars, .EnvVarFile) before running it on the remote machine. If template interpolation fails — e.g. a syntax error or a reference to an unknown variable/sprig function — Provision aborts with this message wrapping the underlying render error. It is thrown before anything is uploaded, so no remote state was changed.

Solutions

  1. Fix the template syntax in execute_command — check for balanced {{ }} braces
  2. Use only the provided variables: .Path, .Vars, .EnvVarFile (and configured template variables)
  3. Run `packer validate` / `packer inspect` to catch template errors before a build
  4. If using custom env vars, ensure they are defined so {{ .Vars }} renders correctly

Example fix

// before
execute_command = "chmod +x {{ .Pathy }}; {{ .Pathy }}"
// after
execute_command = "chmod +x {{ .Path }}; {{ .Vars }} {{ .Path }}"
Defensive patterns

Strategy: validation

Validate before calling

# Validate the template renders before a build; catch bad vars/braces early.
execute_command = "chmod +x {{ .Path }}; {{ .Vars }} {{ .Path }}"
# then:
# packer validate template.pkr.hcl

Prevention

When it happens

Trigger: Calling provision (via `packer build`) with an execute_command containing invalid template syntax such as `{{` without closing braces, an unknown template function like `{{ .Foo }}` when Foo is not a provided variable, or invalid sprig pipeline usage.

Common situations: Typo'd template variables (e.g. `{{ .Pathy }}` instead of `{{ .Path }}`); copying a command with `{{.Vars}}` into a context where env vars were not defined; hand-edited templates with unbalanced `{{` `}}`; mixing legacy JSON template syntax with HCL2 variables.

Related errors


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

Appendix: source

Thrown at provisioner/shell/provisioner.go:315

		ui.Say(fmt.Sprintf("Provisioning with shell script: %s", path))

		log.Printf("Opening %s for reading", path)
		f, err := os.Open(path)
		if err != nil {
			return fmt.Errorf("Error opening shell script: %s", err)
		}
		defer f.Close()

		// Compile the command
		// These are extra variables that will be made available for interpolation.
		generatedData["Vars"] = flattenedEnvVars
		generatedData["EnvVarFile"] = p.config.envVarFile
		generatedData["Path"] = p.config.RemotePath
		p.config.ctx.Data = generatedData

		command, err := interpolate.Render(p.config.ExecuteCommand, &p.config.ctx)
		if err != nil {
			return fmt.Errorf("Error processing command: %s", err)
		}

		// Upload the file and run the command. Do this in the context of
		// a single retryable function so that we don't end up with
		// the case that the upload succeeded, a restart is initiated,
		// and then the command is executed but the file doesn't exist
		// any longer.
		var cmd *packersdk.RemoteCmd
		err = retry.Config{StartTimeout: p.config.StartRetryTimeout}.Run(ctx, func(ctx context.Context) error {
			if _, err := f.Seek(0, 0); err != nil {
				return err
			}

			var r io.Reader = f
			if !p.config.Binary {
				r = &UnixReader{Reader: r}
			}

View on GitHub (pinned to eb36e3c3e4)