hashicorp/terraform · warning

Failed to read file %s

Error message

Failed to read file %s

What it means

Returned by FmtCommand.fmt (fmt.go:146) when os.Open fails for a file that matched a supported extension (so fmt tried to open it for formatting). Because the file already passed os.Stat (the outer loop), an Open failure here typically indicates a transient condition — the file disappeared between stat and open, or permission changed. The error is reported per-file and fmt continues to the next path.

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"))
				continue

View on GitHub (pinned to c9def3e214)

Solutions

  1. Re-run fmt after the racing process completes; the file likely exists again.
  2. Check the file is readable: `ls -l <file>` and `cat <file> >/dev/null`; fix permissions (`chmod +r <file>`) if revoked.
  3. Resolve broken symlinks: `readlink <file>` and point at the real target.
  4. Exclude volatile directories (sync folders, build outputs) from fmt, or run fmt on a stable checkout.

Example fix

# before
$ terraform fmt main.tf
Failed to read file main.tf   # file deleted or chmod'd mid-run

# after
$ ls -l main.tf               # confirm it is back and readable
$ terraform fmt main.tf
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-open the file and confirm readability
f, err := os.Open(path)
if err != nil {
    return fmt.Errorf("cannot open %s for formatting: %w", path, err)
}
defer f.Close()
// pass f to fmt

Try / catch

// On a transient open failure, retry once; surface a per-file warning otherwise.
for attempt := 0; attempt < 2; attempt++ {
    if err := formatOne(path); err == nil { break }
    if attempt == 1 || !isTransient(err) { log.Printf("warning: skipped %s: %v", path, err) }
    time.Sleep(100 * time.Millisecond)
}

Prevention

When it happens

Trigger: os.Open(path) returns an error between a successful os.Stat and the open: the file was deleted (race with another process), permission was revoked (chmod removed read bit), the file was renamed, or an external tool locked it (Windows).

Common situations: Another process (formatter, linter, sync client) deletes/recreates files while fmt runs; the file is a broken symlink; permissions changed mid-run; on Windows, an editor holds an exclusive lock; CI workspace cleanup racing with fmt.

Related errors


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