hashicorp/terraform · error

Error reading %s: %s

Error message

Error reading %s: %s

What it means

Emitted by `loadConfigFile` (cliconfig.go:160) when `ioutil.ReadFile(path)` fails on a CLI config file (`.terraformrc` / `terraform.rc` or a `*.tfrc`/`*.tfrc.json` file). The `%s` placeholders are the file path and the wrapped OS read error. This is distinct from a missing file (handled earlier via `os.Stat`), so it indicates a real I/O failure on a file that exists.

Source

Thrown at internal/command/cliconfig/cliconfig.go:160

		config = envConfig.Merge(config)
	}

	diags = diags.Append(config.Validate())

	return config, diags
}

// loadConfigFile loads the CLI configuration from ".terraformrc" files.
func loadConfigFile(path string) (*Config, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	result := &Config{}

	log.Printf("Loading CLI configuration from %s", path)

	// Read the HCL file and prepare for parsing
	d, err := ioutil.ReadFile(path)
	if err != nil {
		diags = diags.Append(fmt.Errorf("Error reading %s: %s", path, err))
		return result, diags
	}

	// Parse it
	obj, err := hcl.Parse(string(d))
	if err != nil {
		diags = diags.Append(fmt.Errorf("Error parsing %s: %s", path, err))
		return result, diags
	}

	// Build up the result
	if err := hcl.DecodeObject(&result, obj); err != nil {
		diags = diags.Append(fmt.Errorf("Error parsing %s: %s", path, err))
		return result, diags
	}

	// Deal with the provider_installation block, which is not handled using
	// DecodeObject because its structure is not compatible with the

View on GitHub (pinned to c9def3e214)

Solutions

  1. Check the file's permissions and ownership (`ls -l` on the path from the error) and make it readable.
  2. Resolve any broken symlinks in the config path.
  3. If the file is not meant to be used, unset `TF_CLI_CONFIG_FILE`/`TERRAFORM_CONFIG` or move/remove the file.
  4. Retry if the error indicates a transient network/filesystem I/O fault.

Example fix

# before
ls -l ~/.terraformrc   # -rw------- but owned by another user
terraform init
# Error reading /home/user/.terraformrc: permission denied

# after
chmod u+r ~/.terraformrc   # or chown to current user
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check readability of the CLI config file before loading it.
func configReadable(path string) error {
    f, err := os.OpenFile(path, os.O_RDONLY, 0)
    if err != nil {
        return fmt.Errorf("cannot read CLI config %s: %w", path, err)
    }
    return f.Close()
}

Try / catch

// cfg, diags := cliconfig.LoadConfig()
if diags.HasErrors() {
    for _, d := range diags {
        if strings.HasPrefix(d.Description().Summary, "Error reading") {
            // The path in the message names the unreadable file.
            return handleUnreadableConfig(d)
        }
    }
}

Prevention

When it happens

Trigger: Terraform locates a CLI config file that exists but cannot be read — permission denied, file removed between stat and read, or an I/O error from the filesystem.

Common situations: `.terraformrc` with mode 000 or owned by another user; a symlink loop or broken symlink; NFS/network filesystem hiccup; `TF_CLI_CONFIG_FILE` pointing at an unreadable file.

Related errors


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