hashicorp/terraform · warning
Failed to read file
Error message
Failed to read file %s
What it means
Thrown by FmtCommand.fmt when os.Open fails on a file that (a) exists per os.Stat and (b) matches a fmt-supported extension (.tf, .tfvars, .tftest.hcl). The comment notes os.Open's raw error is not end-user-friendly, so Terraform substitutes this generic message. The loop continues to other files.
Solutions
- Confirm read permission: `cat <path>` or `test -r <path> && echo ok`.
- chmod to grant read: `chmod u+r <path>`.
- If a race deleted the file, rerun after stabilizing the directory.
- Check SELinux/AppArmor for read denials (`ls -Z`, audit logs).
Example fix
// before: file is 0000, stat ok but open fails // $ chmod u+r main.tf // after: terraform fmt main.tf succeeds
Defensive patterns
Strategy: validation
Validate before calling
func openable(p string) error {
f, err := os.Open(p)
if err != nil { return fmt.Errorf("%s not readable: %w", p, err) }
f.Close()
return nil
} Prevention
- Ensure read permission (u+r) on .tf/.tfvars files before fmt.
- Avoid races where files are deleted between stat and open.
- Check SELinux/AppArmor if reads fail despite Unix perms.
When it happens
Trigger: Stat succeeded (file existed) but by the time Open ran the file was removed (TOCTOU race); the file's permissions allow stat but not read; the path is a broken symlink that stat resolved but open cannot follow; the file is a special device.
Common situations: File mode denies read to the user (stat ok, open EACCES); a concurrent process deleted the file between stat and open; symlink to a missing target where lstat/stat semantics differ; SELinux denying read.
Related errors
- failed to read stacks plugin stored path file
- No file or directory at
- cannot create temporary file to update credentials
- Cannot read directory
- cannot read
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/98518fcb474e12ec.
Report an issue: GitHub.
Appendix: source
Thrown at internal/command/fmt.go:146
for _, path := range paths {
path = c.normalizePath(path)
info, err := os.Stat(path)
if err != nil {
diags = diags.Append(fmt.Errorf("No file or directory at %s", path))
return diags
}
if info.IsDir() {
dirDiags := c.processDir(path, stdout)
diags = diags.Append(dirDiags)
} else {
fmtd := false
for _, ext := range fmtSupportedExts {
if strings.HasSuffix(path, ext) {
f, err := os.Open(path)
if err != nil {
// Open does not produce error messages that are end-user-appropriate,
// so we'll need to simplify here.
diags = diags.Append(fmt.Errorf("Failed to read file %s", path))
continue
}
fileDiags := c.processFile(c.normalizePath(path), f, stdout, false)
diags = diags.Append(fileDiags)
f.Close()
// Take note that we processed the file.
fmtd = true
// Don't check the remaining extensions.
break
}
}
if !fmtd {
diags = diags.Append(fmt.Errorf("Only .tf, .tfvars, and .tftest.hcl files can be processed with terraform fmt"))
continueView on GitHub (pinned to d32a084675)