{"record":{"id":"5b967b9e54ae43b3","repo":"opentofu/opentofu","slug":"failed-to-upload-script-w","errorCode":null,"errorMessage":"Failed to upload script: %w","messagePattern":"Failed to upload script: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/builtin/provisioners/remote-exec/resource_provisioner.go","lineNumber":269,"sourceCode":"\t\t\tlog.Printf(\"[ERROR] Unable to close provisioner connection: %s\", err.Error())\n\t\t}\n\t}()\n\n\tfor _, script := range scripts {\n\t\tvar cmd *remote.Cmd\n\n\t\toutR, outW := io.Pipe()\n\t\terrR, errW := io.Pipe()\n\t\tdefer outW.Close()\n\t\tdefer errW.Close()\n\n\t\tgo copyUIOutput(o, outR)\n\t\tgo copyUIOutput(o, errR)\n\n\t\tremotePath := comm.ScriptPath()\n\n\t\tif err := comm.UploadScript(remotePath, script); err != nil {\n\t\t\treturn fmt.Errorf(\"Failed to upload script: %w\", err)\n\t\t}\n\n\t\tcmd = &remote.Cmd{\n\t\t\tCommand: shquot.POSIXShell([]string{remotePath}),\n\t\t\tStdout:  outW,\n\t\t\tStderr:  errW,\n\t\t}\n\t\tif err := comm.Start(cmd); err != nil {\n\t\t\treturn fmt.Errorf(\"Error starting script: %w\", err)\n\t\t}\n\n\t\tif err := cmd.Wait(); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Upload a blank follow up file in the same path to prevent residual\n\t\t// script contents from remaining on remote machine\n\t\tempty := bytes.NewReader([]byte(\"\"))","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/opentofu/opentofu/blob/3561785c48c1ce615e7c50261bd351f26053efa2/internal/builtin/provisioners/remote-exec/resource_provisioner.go#L251-L287","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"# Pre-flight from the apply host\nssh user@target 'touch /tmp/.tf-probe && rm /tmp/.tf-probe' || echo 'TMP_NOT_WRITABLE'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["provisioner","remote-exec","upload","ssh"],"backgroundTag":null,"analyzedSha":"3561785c48c1ce615e7c50261bd351f26053efa2","analyzedAt":"2026-08-15T23:27:16.226Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}