hashicorp/terraform · error
invalid syntax
Error message
invalid syntax: %w
What it means
First-line parse failure in ParseBackendStateFile: json.Unmarshal of the version-sniff struct failed, meaning the backend state file (.terraform/terraform.tfstate) is not valid JSON at all. The %w carries the json decoder's offset/reason.
Solutions
- Open .terraform/terraform.tfstate and check it parses as JSON (jq . < file).
- Restore from version control or backup if corrupted.
- If the file is empty/garbage, delete it and run `terraform init` to regenerate.
- Re-save as UTF-8 without BOM and Unix line endings.
Example fix
# diagnose jq . .terraform/terraform.tfstate # regenerate if unrecoverable rm .terraform/terraform.tfstate terraform init
Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: confirm the file is valid JSON before handing it to the parser
if !json.Valid(src) {
return nil, fmt.Errorf("backend state file is not valid JSON; re-run `terraform init`")
} Type guard
func looksLikeBackendState(src []byte) bool {
var sniff struct{ Version int `json:"version"` }
return json.Unmarshal(src, &sniff) == nil && sniff.Version > 0
} Try / catch
f, err := ParseBackendStateFile(src)
if err != nil {
if !json.Valid(src) {
return nil, errors.New("backend state file corrupt; delete it and re-run `terraform init`")
}
return nil, err
} Prevention
- Never hand-edit the backend state file.
- Add .terraform/ to .gitignore and manage config via the backend block.
- Snapshot the workspace before upgrades.
When it happens
Trigger: Pointing Terraform at a backend state file that is empty, truncated, binary (e.g. legacy gob format), or contains a syntax error (trailing comma, unquoted key, BOM, etc.).
Common situations: File corrupted by a crashed write, edited by hand with a typo, replaced by a non-JSON file (e.g. a Terraform state snapshot or a log), or transferred with encoding damage (CRLF/BOM on Windows).
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/8de06fa186028408.
Report an issue: GitHub.
Appendix: source
Thrown at internal/command/workdir/backend_state.go:82
// Returns an error if the content is not valid syntax, or if the file is
// of an unsupported format version.
//
// This does not immediately decode the embedded backend config, and so
// it's possible that a subsequent call to [BackendConfigState.Config] will
// return further errors even if this call succeeds.
func ParseBackendStateFile(src []byte) (*BackendStateFile, error) {
// To avoid any weird collisions with as-yet-unknown future versions of
// 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 {View on GitHub (pinned to d32a084675)