{"record":{"id":"b43af56161beacda","repo":"hashicorp/terraform","slug":"unsupported-backend-state-version-d-you-may-need","errorCode":null,"errorMessage":"unsupported backend state version %d; you may need to use Terraform CLI v%s to work in this directory","messagePattern":"unsupported backend state version (.+?); you may need to use Terraform CLI v(.+?) to work in this directory","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/workdir/backend_state.go","lineNumber":93,"sourceCode":"\ttype VersionSniff struct {\n\t\tVersion   int    `json:\"version\"`\n\t\tTFVersion string `json:\"terraform_version,omitempty\"`\n\t}\n\tvar versionSniff VersionSniff\n\terr := json.Unmarshal(src, &versionSniff)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid syntax: %w\", err)\n\t}\n\tif versionSniff.Version == 0 {\n\t\t// This could either mean that it's explicitly \"version\": 0 or that\n\t\t// the version property is missing. We'll assume the latter here\n\t\t// because state snapshot version 0 was an encoding/gob binary format\n\t\t// rather than a JSON format and so it would be very weird for\n\t\t// that to show up in a JSON file.\n\t\treturn nil, fmt.Errorf(\"invalid syntax: no format version number\")\n\t}\n\tif versionSniff.Version != 3 {\n\t\treturn nil, fmt.Errorf(\"unsupported backend state version %d; you may need to use Terraform CLI v%s to work in this directory\", versionSniff.Version, versionSniff.TFVersion)\n\t}\n\n\t// If we get here then we can be sure that this file at least _thinks_\n\t// it's format version 3.\n\tvar stateFile BackendStateFile\n\terr = json.Unmarshal(src, &stateFile)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid syntax: %w\", err)\n\t}\n\tif stateFile.Backend == nil && stateFile.Remote != nil {\n\t\t// It's very unlikely to get here, but one way it could happen is\n\t\t// if this working directory was most recently used with Terraform v0.8\n\t\t// or earlier, which didn't yet include the concept of backends.\n\t\t// This error message assumes that's the case.\n\t\treturn nil, fmt.Errorf(\"this working directory uses legacy remote state and so must first be upgraded using Terraform v0.9\")\n\t}\n\tif stateFile.Backend != nil && stateFile.StateStore != nil {\n\t\treturn nil, fmt.Errorf(\"encountered a malformed backend state file that contains state for both a 'backend' and a 'state_store' block\")","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/workdir/backend_state.go#L75-L111","documentation":"ParseBackendStateFile found a `version` field but it is not 3 — the only JSON backend-state format Terraform/OpenTofu knows how to read. The message reports the offending version and the TFVersion recorded in the file (the version of Terraform that wrote it), pointing the user to that binary for compatibility.","triggerScenarios":"A backend state file produced by a future Terraform version that bumped the format number, or by an incompatible fork. Reading the file with an older build.","commonSituations":"Downgrading Terraform/OpenTofu after a newer release wrote state, sharing a workspace across major versions, or a CI image pinned to an older version than developers' machines.","solutions":["Upgrade the binary to at least the TFVersion printed in the message (or to the version that wrote the file).","If you must downgrade, run `terraform init` on the newer version first, then `terraform state push`/`pull` to migrate state to a backend the older version understands.","Start a fresh workspace: rm -rf .terraform and re-init on the desired version."],"exampleFix":"# before — older terraform rejects newer backend state file\n\nterraform version  # upgrade to >= the TFVersion in the error message\nterraform init","handlingStrategy":"validation","validationCode":"// pre-flight: gate on supported version\nvar sniff struct {\n    Version   int    `json:\"version\"`\n    TFVersion string `json:\"terraform_version\"`\n}\n_ = json.Unmarshal(src, &sniff)\nif sniff.Version != 3 {\n    return nil, fmt.Errorf(\"backend state v%d written by terraform %s; use that version or re-init\", sniff.Version, sniff.TFVersion)\n}","typeGuard":"func isSupportedBackendVersion(src []byte) bool {\n    var s struct{ Version int `json:\"version\"` }\n    _ = json.Unmarshal(src, &s)\n    return s.Version == 3\n}","tryCatchPattern":null,"preventionTips":["Pin Terraform/OpenTofu versions across dev and CI (.terraform-version, tfenv, tofu version).","Run `terraform init` immediately after any version change."],"tags":["backend","version-mismatch","compatibility","init"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}