{"record":{"id":"28d8c89268661bef","repo":"opentofu/opentofu","slug":"upload-failed-w","errorCode":null,"errorMessage":"Upload failed: %w","messagePattern":"Upload failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/builtin/provisioners/file/resource_provisioner.go","lineNumber":215,"sourceCode":"\n\t// disconnect when the context is canceled, which will close this after\n\t// Apply as well.\n\tgo func() {\n\t\t<-ctx.Done()\n\t\tif err := comm.Disconnect(); err != nil {\n\t\t\tlog.Printf(\"[ERROR] Unable to close provisioner connection: %s\", err.Error())\n\t\t}\n\t}()\n\n\tinfo, err := os.Stat(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// If we're uploading a directory, short circuit and do that\n\tif info.IsDir() {\n\t\tif err := comm.UploadDir(dst, src); err != nil {\n\t\t\treturn fmt.Errorf(\"Upload failed: %w\", err)\n\t\t}\n\t\treturn nil\n\t}\n\n\t// We're uploading a file...\n\tf, err := os.Open(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\n\terr = comm.Upload(dst, f)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Upload failed: %w\", err)\n\t}\n\n\treturn err\n}","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/opentofu/opentofu/blob/3561785c48c1ce615e7c50261bd351f26053efa2/internal/builtin/provisioners/file/resource_provisioner.go#L197-L233","documentation":"The file provisioner wraps communicator errors from uploading a directory (comm.UploadDir) in 'Upload failed: %w'. The underlying cause is typically lost connectivity, permission denial on the remote destination, an invalid destination path, or a full disk on the target.","triggerScenarios":"provisioner \"file\" with source pointing at a directory during apply, where the SSH/WinRM transfer of the directory tree fails mid-operation.","commonSituations":"Destination path not absolute or not writable by the login user; connection dropped through a bastion/NAT timeout; disk full on the target; WinRM path-style mismatches; uploading many small files over a slow link until timeout.","solutions":["Verify connectivity from the same host (manual ssh/winrm to the target) and check the connection block settings.","Make destination an absolute path that exists and is writable by the login user.","Check disk space and directory permissions on the target.","For slow or flaky links, raise connection timeout or upload a single archive and unpack it with remote-exec instead of a directory tree."],"exampleFix":"# before\nevent = \"relative/dir\"  # destination = \"relative/dir\" (ambiguous/unsupported)\nprovisioner \"file\" { source = \"conf/\", destination = \"conf\" }\n\n# after: absolute destination path\nprovisioner \"file\" { source = \"conf/\", destination = \"/etc/myapp/conf\" }","handlingStrategy":"retry","validationCode":"# CI pre-flight from the same host that runs apply\nssh -o BatchMode=yes user@target 'test -w /etc/myapp/conf || echo NOT_WRITABLE'","typeGuard":null,"tryCatchPattern":"if err := comm.UploadDir(dst, src); err != nil {\n    // transient transport failures (EOF, timeout) are retryable;\n    // permission errors are not — inspect the wrapped error\n    if isTransient(err) { time.Sleep(backoff); retry() }\n}","preventionTips":["Use absolute destination paths that exist and are writable by the connection user.","Set realistic connection timeouts for large trees.","Upload one archive and unpack with remote-exec instead of many small files.","Test connectivity from the same host/bastion before apply."],"tags":["provisioner","file","upload","ssh","winrm"],"backgroundTag":null,"analyzedSha":"3561785c48c1ce615e7c50261bd351f26053efa2","analyzedAt":"2026-08-15T23:27:16.226Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}