hashicorp/packer · error

Error processing command: %s

Error message

Error processing command: %s

What it means

Raised in Provision when rendering the provisioner's execute_command template fails. The command string is run through HCL2/Go template interpolation with ExecuteCommandTemplate data (Vars, Path); if the template contains bad syntax or references unknown keys/variables, interpolate.Render returns an error wrapped as "Error processing command: %s". This is a template-authoring error, not a guest-side failure.

Source

Thrown at provisioner/windows-shell/provisioner.go:201

		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()

		// Create environment variables to set before executing the command
		flattenedVars := p.createFlattenedEnvVars()

		// Compile the command
		p.config.ctx.Data = &ExecuteCommandTemplate{
			Vars: flattenedVars,
			Path: p.config.RemotePath,
		}
		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
			}

			if err := comm.Upload(p.config.RemotePath, f, nil); err != nil {
				return fmt.Errorf("Error uploading script: %s", err)
			}

			cmd = &packersdk.RemoteCmd{Command: command}

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Fix the execute_command template: valid fields are only {{ .Path }} and {{ .Vars }} (see ExecuteCommandTemplate); correct typos like {{ .Var }} or {{ .Varriables }}.
  2. Balance all {{ }} braces and escape literal braces if the shell command needs them.
  3. Run `packer validate` / inspect the template interpolation of your variables feeding into execute_command.
  4. Fall back to the default execute_command for windows-shell to confirm the rest of the provisioner works, then re-add customizations incrementally.

Example fix

// before: unknown field
execute_command = ["cmd", "/c", "{{ .Var }} & {{ .Path }}"]
// after
execute_command = ["cmd", "/c", "{{ .Vars }} & {{ .Path }}"]
Defensive patterns

Strategy: validation

Validate before calling

// check only supported fields are referenced
allowed := []string{".Path", ".Vars"}
for _, tok := range regexp.MustCompile(`\{\{\s*\.[A-Za-z]+`).FindAllString(cmd, -1) {
    if !slices.Contains(allowed, strings.TrimSpace(strings.TrimPrefix(tok, "{{"))) {
        return fmt.Errorf("unsupported template field %q in execute_command", tok)
    }
}

Try / catch

rendered, err := interpolate.Render(cfg.ExecuteCommand, ctx)
if err != nil {
    return fmt.Errorf("execute_command template invalid (%v); allowed fields: .Path, .Vars", err)
}

Prevention

When it happens

Trigger: p.config.ctx.Data is set to {Vars, Path} and interpolate.Render(p.config.ExecuteCommand, ...) errors — malformed {{ }} syntax, unknown function, or referencing a variable not exposed on ExecuteCommandTemplate. provisioner.go:199-204. Common with a customized execute_command containing typos like {{ .Var }} instead of {{ .Vars }}.

Common situations: Copy-pasted execute_command from another provisioner (shell vs windows-shell use different fields); stray {{ or }} in a batch command; use of user/template variables without quoting correctly; upgraded templates referencing removed template fields.

Related errors


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