{"record":{"id":"c2aa550abe28b2a4","repo":"hashicorp/terraform","slug":"upload-failed-v","errorCode":null,"errorMessage":"Upload failed: %v","messagePattern":"Upload failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/builtin/provisioners/file/resource_provisioner.go","lineNumber":188,"sourceCode":"\t\treturn err\n\t}\n\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\tcomm.Disconnect()\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: %v\", 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: %v\", err)\n\t}\n\n\treturn err\n}","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/builtin/provisioners/file/resource_provisioner.go#L170-L206","documentation":"The file provisioner's copyFiles function wraps UploadDir failures with 'Upload failed: %v'. When the source path is a directory (info.IsDir() is true at resource_provisioner.go:186), the provisioner calls comm.UploadDir to recursively transfer it to the remote machine. Any error from the communicator (SSH, WinRM) during directory upload propagates with this wrapper.","triggerScenarios":"Running a file provisioner whose 'source' points to a directory, when the communicator's UploadDir method fails. Common causes: SSH/WinRM connection drops mid-transfer, permission denied on the remote destination, insufficient disk space on remote, or the communicator returns an internal I/O error.","commonSituations":"Uploading a directory of configuration files or scripts to a remote instance via the file provisioner during 'terraform apply'. The remote machine has restrictive permissions on the destination path. The SSH connection is unstable or times out during a large directory transfer.","solutions":["Verify the remote destination path is writable by the SSH/WinRM user specified in the connection block.","Check that the source directory exists and is readable locally with `ls -la <source>`.","Increase the connection timeout or add a bastion host if the SSH connection is unstable.","Reduce the directory size or split into smaller transfers if the connection is dropping due to transfer volume."],"exampleFix":"# before\nconnection {\n  type        = \"ssh\"\n  host        = var.ip\n  user        = \"ubuntu\"\n  timeout     = \"30s\"\n}\nprovisioner \"file\" {\n  source      = \"./config-dir\"\n  destination = \"/etc/myapp\"\n}\n\n# after — increase timeout and ensure remote dir exists\nconnection {\n  type        = \"ssh\"\n  host        = var.ip\n  user        = \"ubuntu\"\n  timeout     = \"5m\"\n}\nprovisioner \"remote-exec\" {\n  inline = [\"sudo mkdir -p /etc/myapp && sudo chown ubuntu:ubuntu /etc/myapp\"]\n}\nprovisioner \"file\" {\n  source      = \"./config-dir\"\n  destination = \"/etc/myapp\"\n}","handlingStrategy":"retry","validationCode":"// Before provisioning, verify the source directory exists and is readable\ninfo, err := os.Stat(src)\nif err != nil {\n    return fmt.Errorf(\"source directory not accessible: %w\", err)\n}\nif !info.IsDir() {\n    return fmt.Errorf(\"source is not a directory: %s\", src)\n}\n// Check destination path will be writable (best-effort)\n// via a pre-flight remote-exec check","typeGuard":null,"tryCatchPattern":"// Retry directory upload with exponential backoff\nmaxRetries := 3\nfor i := 0; i < maxRetries; i++ {\n    err := comm.UploadDir(dst, src)\n    if err == nil {\n        break\n    }\n    if i == maxRetries-1 {\n        return fmt.Errorf(\"Upload failed after %d attempts: %v\", maxRetries, err)\n    }\n    time.Sleep(time.Duration(1<<i) * time.Second)\n}","preventionTips":["Ensure the remote destination directory exists and is writable before the file provisioner runs.","Use a remote-exec provisioner with inline commands to create the destination directory first.","Set a generous connection timeout in the connection block for large directory transfers.","Verify SSH key permissions and network stability before applying."],"tags":["terraform","file-provisioner","ssh","upload","connection","go"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}