hashicorp/terraform · error

Error creating temporary directory

Error message

Error creating temporary directory: %s

What it means

Returned by `backendMigrateNonEmptyConfirm` when creating a temp directory to dump both states for the side-by-side confirmation diff fails. `os.MkdirTemp("", "terraform")` returned an error, so the non-empty confirmation flow cannot present the diff.

Solutions

  1. Free space in the system temp directory (`/tmp`) or remount tmpfs larger.
  2. Set `TMPDIR` to a writable, spacious directory: `TMPDIR=/var/tmp terraform init`.
  3. Run `terraform init` with `-force-copy` to skip the non-empty confirmation diff entirely.
  4. Check filesystem permissions and disk space on the temp volume.

Example fix

# before
terraform init   # /tmp full
# after
mkdir -p /var/tmp/tf && TMPDIR=/var/tmp/tf terraform init -force-copy
Defensive patterns

Strategy: validation

Validate before calling

# Ensure a writable temp dir with enough space before init.
TMPDIR=${TMPDIR:-/tmp}
mkdir -p "$TMPDIR" && touch "$TMPDIR/.w" && rm "$TMPDIR/.w" \
  || { echo "TMPDIR $TMPDIR not writable"; exit 1; }
df -h "$TMPDIR"  # confirm free space
terraform init

Try / catch

# Side-step the diff entirely when temp space is constrained:
if ! terraform init >/tmp/init.log 2>&1; then
  grep -q 'Error creating temporary directory' /tmp/init.log \
    && { echo 'Set TMPDIR or rerun with -force-copy' >&2; exit 2; }
  cat /tmp/init.log; exit 1
fi

Prevention

When it happens

Trigger: Fires at the top of `backendMigrateNonEmptyConfirm` when `os.MkdirTemp` fails — OS-level temp space unavailable, `TMPDIR` pointing to a non-writable path, disk full, or the OS refusing the `terraform` prefix.

Common situations: CI runners with a full/no `/tmp`, containers with a read-only or small tmpfs, `TMPDIR` misconfigured to a non-existent directory, or SELinux/AppArmor denying temp creation.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/2a1adcf3da43e3fd. Report an issue: GitHub.

Appendix: source

Thrown at internal/command/meta_backend_migrate.go:527

				strings.TrimSpace(inputBackendMigrateEmpty),
				opts.SourceType, srcWord,
				opts.DestinationType, dstWord),
		}
	}

	return m.confirm(inputOpts)
}

func (m *Meta) backendMigrateNonEmptyConfirm(
	sourceState, destinationState statemgr.Full, opts *backendMigrateOpts) (bool, error) {
	// We need to grab both states so we can write them to a file
	source := sourceState.State()
	destination := destinationState.State()

	// Save both to a temporary
	td, err := os.MkdirTemp("", "terraform")
	if err != nil {
		return false, fmt.Errorf("Error creating temporary directory: %s", err)
	}
	defer os.RemoveAll(td)

	// Helper to write the state
	saveHelper := func(n, path string, s *states.State) error {
		mgr := statemgr.NewFilesystem(path)
		return mgr.WriteState(s)
	}

	// Write the states
	sourcePath := filepath.Join(td, fmt.Sprintf("1-%s.tfstate", opts.SourceType))
	destinationPath := filepath.Join(td, fmt.Sprintf("2-%s.tfstate", opts.DestinationType))
	if err := saveHelper(opts.SourceType, sourcePath, source); err != nil {
		return false, fmt.Errorf("Error saving temporary state: %s", err)
	}
	if err := saveHelper(opts.DestinationType, destinationPath, destination); err != nil {
		return false, fmt.Errorf("Error saving temporary state: %s", err)
	}

View on GitHub (pinned to d32a084675)