hashicorp/terraform · error
invalid syntax: no format version number
Error message
invalid syntax: no format version number
What it means
Thrown by ParseBackendStateFile when the first-pass decode succeeded but the top-level "version" field is 0 (missing or explicitly 0). Format version 0 corresponds to an ancient gob-binary state, never JSON, so a JSON file without a version number is treated as malformed/unsupported. Distinct from an unsupported non-zero version, which has its own error.
Source
Thrown at internal/command/workdir/backend_state.go:90
// the format, we'll do a first pass of decoding just the "version"
// property, and then decode the rest only if we find the version number
// that we're expecting.
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")View on GitHub (pinned to c9def3e214)
Solutions
- Delete the malformed backend state file and re-run `terraform init` to recreate it.
- Restore from .terraform/terraform.tfstate.backup if it has a valid version field.
- Run `terraform init -reconfigure` to rebuild backend metadata from the config.
- Confirm no external tooling is overwriting the backend state file.
Example fix
# before: .terraform/terraform.tfstate backend metadata missing version # invalid syntax: no format version number # after rm .terraform/terraform.tfstate terraform init
Defensive patterns
Strategy: validation
Validate before calling
// validate the backend state file has a version field before full parse
func hasBackendStateVersion(raw []byte) error {
var probe struct{ Version int `json:"version"` }
if err := json.Unmarshal(raw, &probe); err != nil {
return err
}
if probe.Version == 0 {
return fmt.Errorf("missing or zero version field")
}
return nil
} Type guard
// narrow the file to a recognised backend-state shape before using it
func isBackendStateV3(raw []byte) bool {
var probe struct{ Version int `json:"version"` }
if json.Unmarshal(raw, &probe) != nil { return false }
return probe.Version == 3
} Prevention
- Let Terraform own the backend state file; never template or hand-write it.
- Regenerate the file with `terraform init` if the version field is missing.
- Restore from backup if a version line was dropped by a bad merge.
- Confirm no external tooling overwrites backend metadata.
When it happens
Trigger: Reading a backend state file that is valid JSON but lacks a "version" property (or has version: 0). Caused by a file not produced by Terraform, a partially-written file, or content from an unrelated tool.
Common situations: Hand-authored or templated backend state file missing required fields; file overwritten by a deployment script; CI artifact corruption; merge conflict resolved incorrectly leaving the version line out.
Related errors
- invalid syntax: %w
- error unmarshaling lock info: %s
- refresh Ecs sts token err, json.Unmarshal fail: %s
- error reading state: %s
- state file %q locked, but could not unmarshal lock info: %s
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/a0295393b53a78ba.
Report an issue: GitHub.