{"record":{"id":"50d5cc0e89414a77","repo":"hashicorp/terraform","slug":"error-reading-state-s","errorCode":null,"errorMessage":"error reading state: %s","messagePattern":"error reading state: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote/backend_state.go","lineNumber":117,"sourceCode":"\n\t// Create the new state.\n\t_, err := r.client.StateVersions.Create(ctx, r.workspace.ID, options)\n\tif err != nil {\n\t\tr.stateUploadErr = true\n\t\treturn fmt.Errorf(\"error uploading state in compatibility mode: %v\", err)\n\t}\n\treturn err\n}\n\n// Put the remote state.\nfunc (r *remoteClient) Put(state []byte) tfdiags.Diagnostics {\n\tvar diags tfdiags.Diagnostics\n\tctx := context.Background()\n\n\t// Read the raw state into a Terraform state.\n\tstateFile, err := statefile.Read(bytes.NewReader(state))\n\tif err != nil {\n\t\treturn diags.Append(fmt.Errorf(\"error reading state: %s\", err))\n\t}\n\n\tov, err := jsonstate.MarshalOutputs(stateFile.State.RootOutputValues)\n\tif err != nil {\n\t\treturn diags.Append(fmt.Errorf(\"error reading output values: %s\", err))\n\t}\n\to, err := json.Marshal(ov)\n\tif err != nil {\n\t\treturn diags.Append(fmt.Errorf(\"error converting output values to json: %s\", err))\n\t}\n\n\toptions := tfe.StateVersionUploadOptions{\n\t\tStateVersionCreateOptions: tfe.StateVersionCreateOptions{\n\t\t\tLineage:          tfe.String(stateFile.Lineage),\n\t\t\tSerial:           tfe.Int64(int64(stateFile.Serial)),\n\t\t\tMD5:              tfe.String(fmt.Sprintf(\"%x\", md5.Sum(state))),\n\t\t\tForce:            tfe.Bool(r.forcePush),\n\t\t\tJSONStateOutputs: tfe.String(base64.StdEncoding.EncodeToString(o)),","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote/backend_state.go#L99-L135","documentation":"First step of remoteClient.Put: parse the raw bytes Terraform hands it into a statefile.File. This is local parsing, not a network call. Failure means the bytes are not a recognizable Terraform state format — corruption or a version the parser can't read.","triggerScenarios":"statefile.Read returns an error: the byte slice isn't valid JSON state (truncated, binary, plain text), the state 'version' field is higher than this build supports, or magic header/lineage fields are malformed.","commonSituations":"State was hand-edited or partially overwritten; downgrading Terraform across a state-format bump; a non-state file (e.g. plan output) was pointed at the state path; concurrent writers corrupted the in-memory buffer.","solutions":["Inspect the state bytes: confirm it's JSON starting with {\"version\":...,\"terraform_version\":...}.","Use a Terraform version that supports the state schema version in the file (check the 'version' field).","Restore state from the last good TFC/TFE state version snapshot if locally corrupted.","Avoid writing/pushing raw bytes from sources other than `terraform state pull`/`push`."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate bytes are JSON state before pushing\nvar head struct{ Version int `json:\"version\"` }\nif err := json.Unmarshal(state, &head); err != nil { return fmt.Errorf(\"not JSON state: %w\", err) }","typeGuard":"func looksLikeJSONState(b []byte) bool {\n    var h struct{ Version int `json:\"version\"`; TerraformVersion string `json:\"terraform_version\"` }\n    return json.Unmarshal(b, &h) == nil && h.Version > 0\n}","tryCatchPattern":null,"preventionTips":["Never hand-edit state JSON.","Push state only via `terraform state push`.","Don't downgrade Terraform across a state-format version boundary."],"tags":["terraform","remote-backend","state","serialization","corruption"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}