hashicorp/terraform · error

Failed to load state: %s

Error message

Failed to load state: %s

What it means

Inside Meta.backendFromState (meta_backend.go:1493), which is the path taken only by `terraform init -backend=false`. It calls clistate.LocalState.RefreshState() to read the local backend-state cache file (.terraform/terraform.tfstate); this error fires when that read or JSON parse fails. Terraform needs that file to recover which backend/state-store was previously configured.

Source

Thrown at internal/command/meta_backend.go:1493

		"Unable to determine state store init reason",
		"This is a bug in Terraform and should be reported",
	))
	return nil, diags
}

// backendFromState returns the initialized (not configured) backend directly
// from the backend state. This should be used only when a user runs
// `terraform init -backend=false`. This function returns a local backend if
// there is no backend state or no backend configured.
func (m *Meta) backendFromState(_ context.Context) (backend.Backend, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	// Get the path to where we store a local cache of backend configuration
	// if we're using a remote backend. This may not yet exist which means
	// we haven't used a non-local backend before. That is okay.
	statePath := filepath.Join(m.DataDir(), DefaultStateFilename)
	sMgr := &clistate.LocalState{Path: statePath}
	if err := sMgr.RefreshState(); err != nil {
		diags = diags.Append(fmt.Errorf("Failed to load state: %s", err))
		return nil, diags
	}
	s := sMgr.State()
	if s == nil {
		// no state, so return a local backend
		log.Printf("[TRACE] Meta.Backend: backend has not previously been initialized in this working directory")
		return backendLocal.New(), diags
	}

	// Depending on the contents of the backend state file,
	// prepare a backend.Backend in the appropriate way.
	var b backend.Backend
	switch {
	case !s.StateStore.Empty():
		// state_store
		log.Printf("[TRACE] Meta.Backend: working directory was previously initialized for %q state store", s.StateStore.Type)
		var ssDiags tfdiags.Diagnostics
		b, ssDiags = m.savedStateStore(sMgr) // Relies on the state manager's internal state being refreshed above.

View on GitHub (pinned to c9def3e214)

Solutions

  1. Check the wrapped `%s` detail: a JSON error means a corrupt file, a permission error means ownership/mode issues.
  2. Delete the offending .terraform/terraform.tfstate (and .terraform.tfstate.backup) and re-run `terraform init -backend=false`.
  3. Restore correct file ownership/permissions on the .terraform directory if the read was denied.
  4. If you need the saved backend info, recover from source control or backup before deleting.

Example fix

// before: terraform init -backend=false  (fails on corrupt .terraform/terraform.tfstate)
// after: rm -f .terraform/terraform.tfstate* && terraform init -backend=false
Defensive patterns

Strategy: validation

Validate before calling

// Validate the local state cache file is readable+valid JSON before relying on backendFromState.
func checkLocalStateFile(path string) error {
    b, err := os.ReadFile(path)
    if err != nil { return err }
    var v map[string]any
    if err := json.Unmarshal(b, &v); err != nil { return fmt.Errorf("corrupt %s: %w", path, err) }
    return nil
}

Prevention

When it happens

Trigger: Running `terraform init -backend=false` (or any code path using backendFromState) when .terraform/terraform.tfstate is missing, not readable due to file permissions, or contains malformed/truncated JSON.

Common situations: A truncated state cache file left by a crashed/killed process, a checkout where .terraform is partially synced, ownership/permission changes on the .terraform directory, or a disk-full event corrupting the file.

Related errors


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