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 theView on GitHub (pinned to c9def3e214)
Solutions
- Check the file's permissions and ownership (`ls -l` on the path from the error) and make it readable.
- Resolve any broken symlinks in the config path.
- If the file is not meant to be used, unset `TF_CLI_CONFIG_FILE`/`TERRAFORM_CONFIG` or move/remove the file.
- 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
- Ensure `.terraformrc`/`*.tfrc` files are owner-readable.
- Set `TF_CLI_CONFIG_FILE` to an explicit, verified path in automation.
- Resolve broken symlinks in the config path.
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
- Error parsing %s: %s
- The specified plugin cache dir %s cannot be opened: %s
- cannot read %s: %s
- Cannot set both 'source' and 'content'
- Must provide one of 'source' or 'content'
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/6f7c6c07f35bbca8.
Report an issue: GitHub.