opentofu/opentofu · error

failed to prepare working directory: %w

Error message

failed to prepare working directory: %w

What it means

Returned by Dir.ensureDataDir when os.MkdirAll on the data directory (.terraform by default, or $TF_DATA_DIR) fails. Every command that persists per-run state needs this directory; creation fails when a path component exists as a regular file, the location is read-only, or permissions deny writing.

Source

Thrown at internal/command/workdir/dir.go:207

// ModulesDir returns the directory in the [Dir.DataDir] that is used to store
// the cached modules.
func (d *Dir) ModulesDir() string {
	return filepath.Join(d.DataDir(), modulesDir)
}

// ensureDataDir creates the data directory and all of the necessary parent
// directories that lead to it, if they don't already exist.
//
// For directories that already exist ensureDataDir will preserve their
// permissions, while it'll create any new directories to be owned by the user
// running OpenTofu, readable and writable by that user, and readable by
// all other users, or some approximation of that on non-Unix platforms which
// have a different permissions model.
func (d *Dir) ensureDataDir() error {
	err := os.MkdirAll(d.dataDir, 0755)
	if err != nil {
		return fmt.Errorf("failed to prepare working directory: %w", err)
	}
	return nil
}

View on GitHub (pinned to 3561785c48)

Solutions

  1. If .terraform is a file, remove it (rm .terraform) so a directory can be created
  2. Check/fix write permissions: chown -R $USER . or run from a writable checkout
  3. Verify TF_DATA_DIR points to a creatable/writable path; unset it to use the default
  4. Free disk space or quota if MkdirAll reports no space

Example fix

# before: a file named .terraform blocks the directory
$ ls -la | grep terraform
-rw-r--r--  1 user user   0 .terraform
$ tofu init   # failed to prepare working directory: ...
# after
$ rm .terraform && tofu init
Defensive patterns

Strategy: validation

Validate before calling

# Preflight: data dir path must not be blocked by a file, and must be writable
DATA_DIR="${TF_DATA_DIR:-.terraform}"
if [ -f "$DATA_DIR" ]; then
  echo "$DATA_DIR is a file; remove it so a directory can be created" >&2; exit 2
fi
mkdir -p "$DATA_DIR" 2>/dev/null || { echo "cannot create $DATA_DIR (permissions/space?)" >&2; exit 2; }
tofu init

Type guard

func isDataDirPrepErr(err error) bool {
  return err != nil && strings.HasPrefix(err.Error(), "failed to prepare working directory:")
}

Try / catch

if err := cmd.Run(); err != nil {
  if isDataDirPrepErr(unwrapCause(err)) {
    // filesystem issue: surface actionable context rather than retrying blindly
    return fmt.Errorf("%w: check TF_DATA_DIR writability and disk space", err)
  }
  return err
}

Prevention

When it happens

Trigger: A file named .terraform exists where a directory is needed; TF_DATA_DIR points into a read-only filesystem or a path owned by another user; disk quota exhausted; running tofu in a directory where the user has no write permission.

Common situations: CI containers running as a non-root user against a root-owned checkout; artifacts or dotfile managers creating a file named .terraform; NFS/ro mounts; TF_DATA_DIR set to a shared path with restrictive permissions; disk full.

Related errors


AI-assisted analysis of opentofu/opentofu@3561785c48 (2026-08-15). Data as JSON: /api/errors/aefee90f3ff80f26. Report an issue: GitHub.