hashicorp/terraform · error
Error reading as a statefile
Error message
Error reading %s as a statefile: %w
What it means
After successfully opening the file, getStateFromPath calls statefile.Read to decode it. If decoding fails the error is wrapped with the offending path. This means the file exists and is readable but its contents are not a recognizable Terraform state format (or are a corrupted/truncated state).
Solutions
- Confirm the file is a state file and not a plan: `terraform show` auto-detects plans only when given a plan file path, so ensure you pass the actual .tfstate for state.
- Restore from .tfstate.backup if the primary state is corrupt: cp terraform.tfstate.backup terraform.tfstate.
- Inspect the inner %w error for the exact decode failure (JSON syntax, version mismatch).
- If the state is from an incompatible version, use the matching Terraform version or terraform state pull to fetch fresh remote state.
Example fix
# before: pointing at a corrupt/empty state terraform show ./terraform.tfstate # after: restore from backup cp ./terraform.tfstate.backup ./terraform.tfstate terraform show ./terraform.tfstate
Defensive patterns
Strategy: type-guard
Validate before calling
// Sniff the file before decoding to give a clearer error.
func looksLikeState(path string) bool {
b, err := os.ReadFile(path)
if err != nil { return false }
return bytes.Contains(b, []byte("\"version\":")) || bytes.Contains(b, []byte("version ="))
} Type guard
func isStateFile(path string) bool {
f, err := os.Open(path)
if err != nil { return false }
defer f.Close()
var peek map[string]any
return json.NewDecoder(f).Decode(&peek) == nil && peek["version"] != nil
} Try / catch
// If decoding fails, fall back to the backup sibling file.
if _, err := getStateFromPath(path); err != nil {
backup := path + ".backup"
if _, bErr := getStateFromPath(backup); bErr == nil {
log.Printf("primary state unreadable, used %s", backup)
}
} Prevention
- Keep .tfstate.backup as a recovery source for corrupt primary state.
- Ensure state writes are atomic (never interrupt mid-write).
- Confirm you are pointing at a state file, not a plan or tfvars file.
When it happens
Trigger: terraform show <path> where os.Open succeeds but statefile.Read(file) returns an error — JSON/parse failure, unsupported state format version, truncated bytes, or the file is not a state file at all (e.g. a plan file or arbitrary JSON).
Common situations: Pointing `terraform show` at a binary plan file (use the plan path without extension handling) or a tfvars/json file; state file truncated by an interrupted write; state format from a much older/newer Terraform version; accidentally pointing at a backup .tfstate.backup that is partially written.
Related errors
- Error loading statefile
- error selecting workspace
- argument must be a string
- can't display a cloud plan that is currently
- couldn't read information for cloud run
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/07d3fb4c4d21b076.
Report an issue: GitHub.
Appendix: source
Thrown at internal/command/show.go:392
if buildDiags.HasErrors() {
return nil, diags
}
return config, diags
}
// getStateFromPath returns a statefile if the user-supplied path points to a statefile.
func getStateFromPath(path string) (*statefile.File, error) {
file, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("Error loading statefile: %w", err)
}
defer file.Close()
var stateFile *statefile.File
stateFile, err = statefile.Read(file)
if err != nil {
return nil, fmt.Errorf("Error reading %s as a statefile: %w", path, err)
}
return stateFile, nil
}
// getStateFromBackend returns the State for the current workspace, if available.
func getStateFromBackend(b backend.Backend, workspace string) (*statefile.File, error) {
// Get the state store for the given workspace
stateStore, sDiags := b.StateMgr(workspace)
if sDiags.HasErrors() {
return nil, fmt.Errorf("Failed to load state manager: %w", sDiags.Err())
}
// Refresh the state store with the latest state snapshot from persistent storage
if err := stateStore.RefreshState(); err != nil {
return nil, fmt.Errorf("Failed to load state: %w", err)
}
// Get the latest state snapshot and return itView on GitHub (pinned to d32a084675)