hashicorp/terraform · error
Cannot read directory %s
Error message
Cannot read directory %s
What it means
Emitted by terraform fmt's processDir in the default branch of the os.ReadDir error switch — i.e. ReadDir failed for any reason OTHER than the path not existing (the not-exist case is handled separately at fmt.go:239). The raw error is intentionally simplified because ReadDir's messages are not end-user friendly. The %s is the normalized target path.
Source
Thrown at internal/command/fmt.go:243
}
return diags
}
func (c *FmtCommand) processDir(path string, stdout io.Writer) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
log.Printf("[TRACE] terraform fmt: looking for files in %s", path)
entries, err := os.ReadDir(path)
if err != nil {
switch {
case os.IsNotExist(err):
diags = diags.Append(fmt.Errorf("There is no configuration directory at %s", path))
default:
// ReadDir does not produce error messages that are end-user-appropriate,
// so we'll need to simplify here.
diags = diags.Append(fmt.Errorf("Cannot read directory %s", path))
}
return diags
}
for _, info := range entries {
name := info.Name()
if configs.IsIgnoredFile(name) {
continue
}
subPath := filepath.Join(path, name)
if info.IsDir() {
if c.recursive {
subDiags := c.processDir(subPath, stdout)
diags = diags.Append(subDiags)
}
// We do not recurse into child directories by default because we
// want to mimic the file-reading behavior of "terraform plan", etc,View on GitHub (pinned to c9def3e214)
Solutions
- Check and fix directory permissions: `chmod a+rx <dir>` (or grant the terraform process read+execute access).
- Confirm the path is actually a directory and not a file/symlink: `ls -ld <dir>`.
- If on a network/removable mount, verify the mount is healthy and read-write: `mount | grep <dir>`.
- Run terraform as a user that owns or has been granted access to the directory.
Example fix
# before $ terraform fmt ./configs # dir exists but unreadable # after $ chmod a+rx ./configs $ terraform fmt ./configs
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the directory is readable+traversable by the current process.
if err := unix.Access(dir, unix.R_OK|unix.X_OK); err != nil {
return fmt.Errorf("cannot read directory %q: %w; fix permissions first", dir, err)
} Prevention
- Run terraform as a user that owns or has read+execute on the target directory.
- Validate directory permissions in CI setup before the fmt step.
- Avoid running fmt against directories on unhealthy/failing mounts.
When it happens
Trigger: Running `terraform fmt <dir>` where the directory exists but cannot be read, most commonly due to insufficient POSIX permissions (missing read or execute bit on the directory). Also triggers on OS-level errors such as the path being a symlink loop, I/O errors from a failing disk, or the directory being a file/ special device instead of a directory.
Common situations: Directories created by another user with restrictive umask; running terraform as a non-owner; mounted filesystems that became read-only or failed; ACLs denying the current process. Containers where the bind-mounted directory lacks read access for the terraform process UID.
Related errors
- cannot search %s: %s
- error deleting workspace %s: %w
- Error reading %s: %s
- cannot read %s: %s
- cannot create temporary file to update credentials: %s
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/cb6b6b1566d49660.
Report an issue: GitHub.