hashicorp/terraform · error

Error creating temporary file for upload: %s

Error message

Error creating temporary file for upload: %s

What it means

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.

Source

Thrown at internal/communicator/ssh/communicator.go:659

		return errors.New(string(message))
	}

	return nil
}

var testUploadSizeHook func(size int64)

func scpUploadFile(dst string, src io.Reader, w io.Writer, r *bufio.Reader, size int64) error {
	if testUploadSizeHook != nil {
		testUploadSizeHook(size)
	}

	if size == 0 {
		// Create a temporary file where we can copy the contents of the src
		// so that we can determine the length, since SCP is length-prefixed.
		tf, err := ioutil.TempFile("", "terraform-upload")
		if err != nil {
			return fmt.Errorf("Error creating temporary file for upload: %s", err)
		}
		defer os.Remove(tf.Name())
		defer tf.Close()

		log.Println("[DEBUG] Copying input data into temporary file so we can read the length")
		if _, err := io.Copy(tf, src); err != nil {
			return err
		}

		// Sync the file so that the contents are definitely on disk, then
		// read the length of it.
		if err := tf.Sync(); err != nil {
			return fmt.Errorf("Error creating temporary file for upload: %s", err)
		}

		// Seek the file to the beginning so we can re-read all of it
		if _, err := tf.Seek(0, 0); err != nil {
			return fmt.Errorf("Error creating temporary file for upload: %s", err)

View on GitHub (pinned to c9def3e214)

Solutions

  1. Check available disk space and inodes in the system temp directory (df -h /tmp, df -i /tmp).
  2. Ensure the process has write permission to the temp directory.
  3. Set TMPDIR to a location with adequate free space.
  4. If possible, pass an *os.File or *bytes.Reader to Upload so the size is known and temp buffering is skipped.

Example fix

// before
r := someCustomReader{} // size unknown, forces temp file
comm.Upload(path, r)

// after
data, _ := io.ReadAll(r)
comm.Upload(path, bytes.NewReader(data)) // size known, no temp file
Defensive patterns

Strategy: validation

Validate before calling

// Ensure temp directory is writable before upload
func validateTempDir() error {
    tf, err := ioutil.TempFile("", "terraform-upload-test")
    if err != nil {
        return fmt.Errorf("temp directory not writable: %w", err)
    }
    tf.Close()
    os.Remove(tf.Name())
    return nil
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/4598a213a09538dc. Report an issue: GitHub.