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
- Ensure the remote machine has a working default shell (e.g., /bin/bash).
- Verify the SSH user has permission to execute commands via the exec channel.
- Check that any security software on the remote is not quarantining or removing uploaded scripts.
- 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
- Ensure the remote machine has a functional default shell (/bin/bash or /bin/sh).
- Verify the SSH user has exec channel permissions in the remote sshd_config.
- Use 'inline' commands instead of uploaded scripts if the remote filesystem is restrictive.
- Check that security software is not removing uploaded scripts before execution.
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
- Failed to upload script
- Error reading script
- Failed to open script
- Cannot quote scp command, target platform unknown
- Connection Error: StatusCode
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)