{"record":{"id":"4598a213a09538dc","repo":"hashicorp/terraform","slug":"error-creating-temporary-file-for-upload-s","errorCode":null,"errorMessage":"Error creating temporary file for upload: %s","messagePattern":"Error creating temporary file for upload: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/communicator/ssh/communicator.go","lineNumber":659,"sourceCode":"\t\treturn errors.New(string(message))\n\t}\n\n\treturn nil\n}\n\nvar testUploadSizeHook func(size int64)\n\nfunc scpUploadFile(dst string, src io.Reader, w io.Writer, r *bufio.Reader, size int64) error {\n\tif testUploadSizeHook != nil {\n\t\ttestUploadSizeHook(size)\n\t}\n\n\tif size == 0 {\n\t\t// Create a temporary file where we can copy the contents of the src\n\t\t// so that we can determine the length, since SCP is length-prefixed.\n\t\ttf, err := ioutil.TempFile(\"\", \"terraform-upload\")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Error creating temporary file for upload: %s\", err)\n\t\t}\n\t\tdefer os.Remove(tf.Name())\n\t\tdefer tf.Close()\n\n\t\tlog.Println(\"[DEBUG] Copying input data into temporary file so we can read the length\")\n\t\tif _, err := io.Copy(tf, src); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Sync the file so that the contents are definitely on disk, then\n\t\t// read the length of it.\n\t\tif err := tf.Sync(); err != nil {\n\t\t\treturn fmt.Errorf(\"Error creating temporary file for upload: %s\", err)\n\t\t}\n\n\t\t// Seek the file to the beginning so we can re-read all of it\n\t\tif _, err := tf.Seek(0, 0); err != nil {\n\t\t\treturn fmt.Errorf(\"Error creating temporary file for upload: %s\", err)","sourceCodeStart":641,"sourceCodeEnd":677,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/communicator/ssh/communicator.go#L641-L677","documentation":"Raised in scpUploadFile when ioutil.TempFile(\"\", \"terraform-upload\") fails. When the uploaded file's size is unknown (size == 0), the communicator must buffer the entire input into a local temp file to measure its length because SCP is a length-prefixed protocol. This error means the local OS could not create that temp file.","triggerScenarios":"An io.Reader whose concrete type is not *os.File, *bytes.Buffer, *bytes.Reader, or *strings.Reader is passed to Upload, so size defaults to 0 and triggers temp-file buffering. The OS then fails to create a temp file in the system temp directory.","commonSituations":"The local system temp directory (TMPDIR/TEMP) is full, has no free inodes, or the process lacks write permission to it. Common in containers with a small /tmp, CI runners with disk pressure, or when TMPDIR points to a read-only mount.","solutions":["Check available disk space and inodes in the system temp directory (df -h /tmp, df -i /tmp).","Ensure the process has write permission to the temp directory.","Set TMPDIR to a location with adequate free space.","If possible, pass an *os.File or *bytes.Reader to Upload so the size is known and temp buffering is skipped."],"exampleFix":"// before\nr := someCustomReader{} // size unknown, forces temp file\ncomm.Upload(path, r)\n\n// after\ndata, _ := io.ReadAll(r)\ncomm.Upload(path, bytes.NewReader(data)) // size known, no temp file","handlingStrategy":"validation","validationCode":"// Ensure temp directory is writable before upload\nfunc validateTempDir() error {\n    tf, err := ioutil.TempFile(\"\", \"terraform-upload-test\")\n    if err != nil {\n        return fmt.Errorf(\"temp directory not writable: %w\", err)\n    }\n    tf.Close()\n    os.Remove(tf.Name())\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass *os.File or *bytes.Reader to Upload so size is known and temp buffering is avoided.","Set TMPDIR to a location with adequate free disk space and inodes.","In containers, ensure /tmp is writable and has a reasonable size limit."],"tags":["scp","temp-file","disk-space","upload","terraform"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}