opentofu/opentofu · error
Failed to upload script: %w
Error message
Failed to upload script: %w
What it means
While running each script, remote-exec first uploads it to the target with comm.UploadScript; a transport-level failure during that upload (not script execution) is wrapped in 'Failed to upload script'. Causes include an unwritable remote temp directory, connection loss, disk full, or timeouts.
Source
Thrown at internal/builtin/provisioners/remote-exec/resource_provisioner.go:269
log.Printf("[ERROR] Unable to close provisioner connection: %s", err.Error())
}
}()
for _, script := range scripts {
var cmd *remote.Cmd
outR, outW := io.Pipe()
errR, errW := io.Pipe()
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: %w", err)
}
cmd = &remote.Cmd{
Command: shquot.POSIXShell([]string{remotePath}),
Stdout: outW,
Stderr: errW,
}
if err := comm.Start(cmd); err != nil {
return fmt.Errorf("Error starting script: %w", 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(""))View on GitHub (pinned to 3561785c48)
Solutions
- Verify the login user can write to the remote temp directory used for scripts (e.g. /tmp) — test with a manual session.
- Re-check SSH/WinRM and bastion stability during apply, not just at connect time.
- Increase the connection timeout and trim script size (or fetch payloads from object storage instead).
- Retry the apply once the environment is fixed — provisioners only run on resource creation.
Defensive patterns
Strategy: retry
Validate before calling
# Pre-flight from the apply host ssh user@target 'touch /tmp/.tf-probe && rm /tmp/.tf-probe' || echo 'TMP_NOT_WRITABLE'
Prevention
- Ensure the login user can write the remote temp dir (e.g. /tmp) on hardened images.
- Keep scripts small; fetch large payloads from artifact storage instead.
- Set a connection timeout larger than the slowest expected upload.
When it happens
Trigger: comm.UploadScript failing after a successful connection: the remote script path (ScriptPath, typically under /tmp) is not writable, the connection drops between connect and upload, or the transfer exceeds the communicator timeout.
Common situations: Hardened images where /tmp is noexec/read-only for the login user; disk-full targets; bastion idle timeouts killing the session mid-upload; very large scripts on slow links.
Related errors
- Upload failed: %w
- Error starting script: %w
- Failed to open script '%s': %w
- missing provisioner schema
- Failed to upload state to %v: %w
AI-assisted analysis of opentofu/opentofu@3561785c48 (2026-08-15).
Data as JSON: /api/errors/5b967b9e54ae43b3.
Report an issue: GitHub.