{"record":{"id":"bdfae04bd37c8eb9","repo":"hashicorp/terraform","slug":"failed-to-load-the-backend-state-file-s","errorCode":null,"errorMessage":"Failed to load the backend state file: %s","messagePattern":"Failed to load the backend state file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/meta_backend.go","lineNumber":935,"sourceCode":"\t//\n\t// The remainder of this code often confusingly refers to this as a \"state\",\n\t// so it's unfortunately important to remember that this is not actually\n\t// what we _usually_ think of as \"state\", and is instead a local working\n\t// directory \"backend configuration state\" that is never persisted anywhere.\n\t//\n\t// Since the \"real\" state has since moved on to be represented by\n\t// states.State, we can recognize the special meaning of state that applies\n\t// to this function and its callees by their continued use of the\n\t// otherwise-obsolete terraform.State.\n\t// ------------------------------------------------------------------------\n\n\t// Get the path to where we store a local cache of backend configuration\n\t// if we're using a remote backend. This may not yet exist which means\n\t// we haven't used a non-local backend before. That is okay.\n\tstatePath := filepath.Join(m.DataDir(), DefaultStateFilename)\n\tsMgr := &clistate.LocalState{Path: statePath}\n\tif err := sMgr.RefreshState(); err != nil {\n\t\tdiags = diags.Append(fmt.Errorf(\"Failed to load the backend state file: %s\", err))\n\t\treturn nil, diags\n\t}\n\n\t// Load the state, it must be non-nil for the tests below but can be empty\n\ts := sMgr.State()\n\tif s == nil {\n\t\tlog.Printf(\"[TRACE] Meta.Backend: backend has not previously been initialized in this working directory\")\n\t\ts = workdir.NewBackendStateFile()\n\t} else if s.Backend != nil {\n\t\tlog.Printf(\"[TRACE] Meta.Backend: working directory was previously initialized for %q backend\", s.Backend.Type)\n\t} else if s.StateStore != nil {\n\t\tlog.Printf(\"[TRACE] Meta.Backend: working directory was previously initialized for %q state_store using provider %q, version %s\",\n\t\t\ts.StateStore.Type,\n\t\t\ts.StateStore.Provider.Source,\n\t\t\ts.StateStore.Provider.Version)\n\t} else {\n\t\tlog.Printf(\"[TRACE] Meta.Backend: working directory was previously initialized but has no backend (is using legacy remote state?)\")\n\t}","sourceCodeStart":917,"sourceCodeEnd":953,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/meta_backend.go#L917-L953","documentation":"Thrown in Meta.Backend (the main backend/bootstrap entry) when clistate.LocalState.RefreshState fails reading the local backend-cache file at <DataDir>/terraform.tfstate. That file holds the working directory's backend/state_store configuration snapshot, not real Terraform state. A read or parse failure here means the cached backend config is unreadable.","triggerScenarios":"sMgr.RefreshState() returns an error reading filepath.Join(m.DataDir(), DefaultStateFilename). Triggers: the file exists but is not valid JSON / corrupt state-file version, the file is unreadable due to permissions, or the on-disk bytes were truncated by a crashed write/SIGKILL during a prior init.","commonSituations":"Disk full or editor crash mid-write corrupted .terraform/terraform.tfstate; a user hand-edited the cache file; permissions changed (root-owned file after running under sudo); NFS/network FS returned an I/O error; mixing OpenTofu and Terraform CLI on the same working dir produced an incompatible cache schema.","solutions":["Inspect <DataDir>/terraform.tfstate (usually .terraform/terraform.tfstate): confirm it is valid JSON and well-formed.","Restore from version control or a known-good copy if corrupted; otherwise delete it and re-run `tofu init` to regenerate the cache.","Fix filesystem permissions so the current user owns and can read .terraform/.","Avoid running init under a different user (root vs. your account) that leaves the cache unreadable.","If the file is fine but a network/FS transient caused the read failure, retry the command."],"exampleFix":"// before: .terraform/terraform.tfstate is corrupt/hand-edited\ntofu plan  # -> Failed to load the backend state file\n\n// after: drop the cache and reinitialize\nrm .terraform/terraform.tfstate\ntofu init","handlingStrategy":"validation","validationCode":"// Validate the backend cache file before Meta.Backend reads it.\nfunc validateBackendCache(dataDir string) error {\n    p := filepath.Join(dataDir, DefaultStateFilename) // .terraform/terraform.tfstate\n    b, err := os.ReadFile(p)\n    if errors.Is(err, os.ErrNotExist) { return nil } // absent is fine\n    if err != nil { return err }\n    var v json.RawMessage\n    if err := json.Unmarshal(b, &v); err != nil {\n        return fmt.Errorf(\"backend cache file %s is corrupt: %w\", p, err)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := sMgr.RefreshState(); err != nil {\n    if errors.Is(err, os.ErrNotExist) {\n        // acceptable: treat as uninitialized\n    } else if isJSONParseErr(err) {\n        diags = diags.Append(fmt.Errorf(\"backend cache file is corrupt; run 'tofu init -reconfigure': %s\", err))\n    } else {\n        diags = diags.Append(fmt.Errorf(\"Failed to load the backend state file: %s\", err))\n    }\n    return nil, diags\n}","preventionTips":["Never hand-edit .terraform/terraform.tfstate.","Commit/restore this file via CI cache keyed on config hash, or let init regenerate it.","Run init under the same user that will run plan/apply to keep file ownership consistent.","Avoid running init under sudo/root which can leave the cache unreadable."],"tags":["backend","local-state","init","cache-file","filesystem"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}