hashicorp/terraform · warning

Failed to generate diff for %s: %s

Error message

Failed to generate diff for %s: %s

What it means

Returned by FmtCommand.processFile (fmt.go:213) when bytesDiff fails to produce a unified diff between the original and reformatted source (only when -diff is set and the content changed). bytesDiff writes both byte slices to os.CreateTemp temp files and shells out to the external `diff` command; the error message includes the path and the underlying error for diagnosis.

Source

Thrown at internal/command/fmt.go:213

	result := c.formatSourceCode(src, path)

	if !bytes.Equal(src, result) {
		// Something was changed
		if c.list {
			fmt.Fprintln(w, path)
		}
		if c.write {
			err := os.WriteFile(path, result, 0644)
			if err != nil {
				diags = diags.Append(fmt.Errorf("Failed to write %s", path))
				return diags
			}
		}
		if c.diff {
			diff, err := bytesDiff(src, result, path)
			if err != nil {
				diags = diags.Append(fmt.Errorf("Failed to generate diff for %s: %s", path, err))
				return diags
			}
			w.Write(diff)
		}
	}

	if !c.list && !c.write && !c.diff {
		_, err = w.Write(result)
		if err != nil {
			diags = diags.Append(fmt.Errorf("Failed to write result"))
		}
	}

	return diags
}

func (c *FmtCommand) processDir(path string, stdout io.Writer) tfdiags.Diagnostics {
	var diags tfdiags.Diagnostics

View on GitHub (pinned to c9def3e214)

Solutions

  1. Install the `diff` utility (part of `diffutils`/`coreutils`): in Debian/Alpine containers `apt-get install -y diffutils` or `apk add diffutils`.
  2. Ensure the directory containing `diff` is on PATH for the Terraform process: `which diff` and export PATH.
  3. Ensure TMPDIR/TEMP is writable and has free space for the two temp files.
  4. If you cannot install `diff`, drop the -diff flag and inspect changes via -write=false output redirection.

Example fix

# before (minimal container)
$ terraform fmt -diff main.tf
Failed to generate diff for main.tf: exec: "diff": executable file not found in $PATH

# after
$ apk add --no-cache diffutils   # or apt-get install -y diffutils
terraform fmt -diff main.tf
Defensive patterns

Strategy: validation

Validate before calling

// Probe for the diff utility and a usable temp dir before enabling -diff
if c.diff {
    if _, err := exec.LookPath("diff"); err != nil {
        return errors.New("-diff requires the 'diff' utility on PATH")
    }
    if f, err := os.CreateTemp("", ""); err != nil {
        return fmt.Errorf("-diff needs a writable temp dir: %w", err)
    } else { f.Close(); os.Remove(f.Name()) }
}

Type guard

// DiffAvailable reports whether the external `diff` command exists on PATH.
func DiffAvailable() bool {
    _, err := exec.LookPath("diff")
    return err == nil
}

Try / catch

// If -diff generation fails, degrade gracefully by continuing without the diff rather than failing the whole fmt run.
if diff, err := bytesDiff(src, result, path); err != nil {
    log.Printf("warning: could not generate diff for %s (%v)", path, err)
} else {
    w.Write(diff)
}

Prevention

When it happens

Trigger: bytesDiff returns a non-nil error: os.CreateTemp fails (no temp dir / disk full), the `diff` binary is not on PATH (exec.LookUp fails → exec error), the external `diff` command exits abnormally with no output (signal, crash), or writing the temp files fails.

Common situations: Minimal containers (distroless, scratch-based) without the `diff` utility installed; PATH not inherited in the shell running Terraform; /tmp or TMPDIR full or read-only; `diff` binary missing on Windows unless a Unix-y toolchain is installed.

Related errors


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