{"record":{"id":"796c32a50015a248","repo":"hashicorp/terraform","slug":"attempted-to-encode-a-malformed-backend-state-file-796c32","errorCode":null,"errorMessage":"attempted to encode a malformed backend state file; state store type is missing","messagePattern":"attempted to encode a malformed backend state file; state store type is missing","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/workdir/statestore_config_state.go","lineNumber":49,"sourceCode":"\tHash               uint64                          `json:\"hash\"`                 // Hash of the state_store block's configuration, including the nested provider block\n\tProviderSupplyMode getproviders.ProviderSupplyMode `json:\"provider_supply_mode\"` // How the provider was supplied to Terraform during the init operation that created this config state.\n}\n\n// Empty returns true if there is no active state store.\nfunc (s *StateStoreConfigState) Empty() bool {\n\treturn s == nil || s.Type == \"\"\n}\n\n// Validate returns true if there are no missing expected values, and\n// important values have been validated, e.g. FQNs. When the config is\n// invalid an error will be returned.\nfunc (s *StateStoreConfigState) Validate() error {\n\t// Are any bits of data totally missing?\n\tif s.Empty() {\n\t\treturn fmt.Errorf(\"attempted to encode a malformed backend state file; data is empty\")\n\t}\n\tif s.Type == \"\" {\n\t\treturn fmt.Errorf(\"attempted to encode a malformed backend state file; state store type is missing\")\n\t}\n\tif s.Provider == nil {\n\t\treturn fmt.Errorf(\"attempted to encode a malformed backend state file; provider data is missing\")\n\t}\n\tif s.ConfigRaw == nil {\n\t\treturn fmt.Errorf(\"attempted to encode a malformed backend state file; state_store configuration data is missing\")\n\t}\n\n\t// Validity of data that is there\n\terr := s.Provider.Source.Validate()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"state store is not valid: %w\", err)\n\t}\n\n\t// Version information is required if the provider isn't builtin or unmanaged by Terraform\n\tswitch s.ProviderSupplyMode {\n\tcase getproviders.BuiltIn, getproviders.Reattached, getproviders.DevOverride:\n\t\t// These modes do not require version information","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/workdir/statestore_config_state.go#L31-L67","documentation":"StateStoreConfigState.Validate() found Empty() == false (Type was previously something?) Actually the order is: Empty() check passes (so s != nil and Type != \"\" would normally hold), but the next guard checks Type == \"\" again. In practice this branch is unreachable given Empty()'s definition (Empty returns true when Type==\"\"). Hitting it means Type was mutated between checks, or a logic bug.","triggerScenarios":"Concurrent mutation of the StateStoreConfigState between the Empty() and Type==\"\" checks, or a fork that changed Empty()'s definition. Effectively unreachable in stock Terraform.","commonSituations":"Race condition on the struct, custom fork, or reflective tampering. Should never occur in normal single-threaded init/plan/apply.","solutions":["Treat as a bug: report it with a reproduction case.","Ensure StateStoreConfigState is not shared across goroutines; copy before encoding.","Populate Type explicitly when constructing the struct."],"exampleFix":"// ensure Type is set before Validate()\nif s.Type == \"\" { s.Type = \"kubernetes\" }","handlingStrategy":"validation","validationCode":"// pre-flight: combine the two checks into one to avoid races\nif s == nil || s.Type == \"\" {\n    return errors.New(\"state store type is missing\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Don't share StateStoreConfigState across goroutines without synchronisation.","Prefer value semantics: copy before passing to encoder."],"tags":["backend","state-store","validate","unreachable","race"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}