hashicorp/terraform · error
unsupported backend state version
Error message
unsupported backend state version %d; you may need to use Terraform CLI v%s to work in this directory
What it means
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.
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.
Example fix
# before — older terraform rejects newer backend state file terraform version # upgrade to >= the TFVersion in the error message terraform init
Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: gate on supported version
var sniff struct {
Version int `json:"version"`
TFVersion string `json:"terraform_version"`
}
_ = json.Unmarshal(src, &sniff)
if sniff.Version != 3 {
return nil, fmt.Errorf("backend state v%d written by terraform %s; use that version or re-init", sniff.Version, sniff.TFVersion)
} Type guard
func isSupportedBackendVersion(src []byte) bool {
var s struct{ Version int `json:"version"` }
_ = json.Unmarshal(src, &s)
return s.Version == 3
} Prevention
- Pin Terraform/OpenTofu versions across dev and CI (.terraform-version, tfenv, tofu version).
- Run `terraform init` immediately after any version change.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- encountered a malformed backend state file that contains…
- encountered a malformed backend state file with a…
- Error asking for state migration action
- Error copying state from the previous %[1]q %[2]s to the…
- Error creating temporary directory
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/b43af56161beacda.
Report an issue: GitHub.
Appendix: source
Thrown at internal/command/workdir/backend_state.go:93
type VersionSniff struct {
Version int `json:"version"`
TFVersion string `json:"terraform_version,omitempty"`
}
var versionSniff VersionSniff
err := json.Unmarshal(src, &versionSniff)
if err != nil {
return nil, fmt.Errorf("invalid syntax: %w", err)
}
if versionSniff.Version == 0 {
// This could either mean that it's explicitly "version": 0 or that
// the version property is missing. We'll assume the latter here
// because state snapshot version 0 was an encoding/gob binary format
// rather than a JSON format and so it would be very weird for
// that to show up in a JSON file.
return nil, fmt.Errorf("invalid syntax: no format version number")
}
if versionSniff.Version != 3 {
return 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)
}
// If we get here then we can be sure that this file at least _thinks_
// it's format version 3.
var stateFile BackendStateFile
err = json.Unmarshal(src, &stateFile)
if err != nil {
return nil, fmt.Errorf("invalid syntax: %w", err)
}
if stateFile.Backend == nil && stateFile.Remote != nil {
// It's very unlikely to get here, but one way it could happen is
// if this working directory was most recently used with Terraform v0.8
// or earlier, which didn't yet include the concept of backends.
// This error message assumes that's the case.
return nil, fmt.Errorf("this working directory uses legacy remote state and so must first be upgraded using Terraform v0.9")
}
if stateFile.Backend != nil && stateFile.StateStore != nil {
return nil, fmt.Errorf("encountered a malformed backend state file that contains state for both a 'backend' and a 'state_store' block")View on GitHub (pinned to d32a084675)