hashicorp/terraform · error

Error starting script

Error message

Error starting script: %v

What it means

The remote-exec provisioner's runScripts function wraps comm.Start failures with 'Error starting script: %v'. After successfully uploading the script to the remote machine, it constructs a remote.Cmd and calls comm.Start to execute it. If the remote command cannot be started (e.g., the script path is invalid, the shell is unavailable, or the SSH session has an execution error), this error is returned.

Solutions

  1. Ensure the remote machine has a working default shell (e.g., /bin/bash).
  2. Verify the SSH user has permission to execute commands via the exec channel.
  3. Check that any security software on the remote is not quarantining or removing uploaded scripts.
  4. Use the 'inline' attribute instead of 'script'/'scripts' to avoid file-based execution if the remote filesystem is problematic.

Example fix

# before — script upload + exec may fail on restricted remotes
provisioner "remote-exec" {
  script = "${path.module}/deploy.sh"
}

# after — use inline to avoid file-based execution issues
provisioner "remote-exec" {
  inline = [
    "#!/bin/bash",
    "set -e",
    "echo 'deploying...'",
    "# your commands here"
  ]
}
Defensive patterns

Strategy: retry

Validate before calling

// Verify the remote shell is available before starting
// (check via a simple echo command in a pre-flight remote-exec)
// Ensure ScriptPath returns a path on a writable, executable filesystem

Try / catch

// Retry command start
for i := 0; i < 3; i++ {
    err := comm.Start(cmd)
    if err == nil {
        break
    }
    if i == 2 {
        return fmt.Errorf("Error starting script after retries: %v", err)
    }
    time.Sleep(time.Duration(i+1) * time.Second)
}

Prevention

When it happens

Trigger: Calling comm.Start(cmd) at resource_provisioner.go:278 after a successful script upload. The communicator fails to start the remote command. Causes include the remote shell not being available, the script file having been removed between upload and execution, or the SSH channel for command execution failing to open.

Common situations: The remote machine's default shell is misconfigured or unavailable. The uploaded script path (from comm.ScriptPath) is on a read-only filesystem or was cleaned up by a security agent. The SSH session's exec channel is restricted by the remote sshd configuration. The script lacks execute permissions on the remote.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/bf30f9b459b0a26a. Report an issue: GitHub.

Appendix: source

Thrown at internal/builtin/provisioners/remote-exec/resource_provisioner.go:279

		defer outW.Close()
		defer errW.Close()

		go copyUIOutput(o, outR)
		go copyUIOutput(o, errR)

		remotePath := comm.ScriptPath()

		if err := comm.UploadScript(remotePath, script); err != nil {
			return fmt.Errorf("Failed to upload script: %v", err)
		}

		cmd = &remote.Cmd{
			Command: remotePath,
			Stdout:  outW,
			Stderr:  errW,
		}
		if err := comm.Start(cmd); err != nil {
			return fmt.Errorf("Error starting script: %v", err)
		}

		if err := cmd.Wait(); err != nil {
			return err
		}

		// Upload a blank follow up file in the same path to prevent residual
		// script contents from remaining on remote machine
		empty := bytes.NewReader([]byte(""))
		if err := comm.Upload(remotePath, empty); err != nil {
			// This feature is best-effort.
			log.Printf("[WARN] Failed to upload empty follow up script: %v", err)
		}
	}

	return nil
}

View on GitHub (pinned to d32a084675)