hashicorp/terraform · error

Error reading %s as a statefile: %w

Error message

Error reading %s as a statefile: %w

What it means

Wrapped error from getStateFromPath when os.Open succeeded but statefile.Read(file) failed to parse the contents as a Terraform state file. This means the file exists and is readable but its bytes are not a valid state document (wrong magic, corrupt JSON, or it is actually a plan/other file). It confirms the path resolved to a file, just not a state file.

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 it

View on GitHub (pinned to c9def3e214)

Solutions

  1. Confirm the file is a genuine state file: it should contain a top-level 'version' and 'serial' field in JSON.
  2. If it is a plan file, ensure you are not corrupting it; use 'terraform show -json <plan>' appropriately.
  3. Restore the state file from a backup if it is truncated/corrupt.
  4. Generate the state file with a compatible Terraform version.

Example fix

// before: 'terraform show ./backup.json' where backup.json is a plan export
// after: point at a real state file
$ terraform show ./terraform.tfstate
Defensive patterns

Strategy: type-guard

Validate before calling

// Pre-flight: sniff the file to decide if it looks like a state file before passing to 'terraform show'
package main

import "encoding/json"

func looksLikeStateFile(path string) error {
	b, err := os.ReadFile(path)
	if err != nil { return err }
	var probe struct{ Version int `json:"version"`; Serial int `json:"serial"` }
	if err := json.Unmarshal(b, &probe); err != nil {
		return fmt.Errorf("%s is not valid JSON state; not a state file", path)
	}
	if probe.Version == 0 { return fmt.Errorf("%s missing state 'version' field", path) }
	return nil
}

Type guard

// Guard: narrow a file path to a likely state file before use
func isLikelyStateFile(path string) bool {
	b, err := os.ReadFile(path)
	if err != nil { return false }
	var probe struct{ Version int `json:"version"` }
	if err := json.Unmarshal(b, &probe); err != nil { return false }
	return probe.Version > 0
}

Prevention

When it happens

Trigger: Running 'terraform show <path>' where <path> is a plan file (binary or JSON plan bookmark), a random JSON/text file, a truncated state file, or a state file written by an incompatible Terraform version whose format statefile.Read rejects.

Common situations: Pointing 'terraform show' at a saved plan (should be handled by plan parser, but if that also failed this is the fallback error); state file truncated by a crashed run; manually concatenated/edited state JSON; version skew between writer and reader CLI.

Related errors


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