hashicorp/terraform · error
encountered a malformed backend state file with a 'state_sto
Error message
encountered a malformed backend state file with a 'state_store' block that is missing the required 'provider_supply_mode' property
What it means
A state_store block must record how its provider was supplied via provider_supply_mode (one of: builtin, managed-by-terraform, reattached, dev-override — see getproviders.ProviderSupplyMode). The check at backend_state.go:113 rejects an empty value early because later code (statestore_config_state.go:65) branches on it and would otherwise produce confusing downstream errors about missing version data.
Source
Thrown at internal/command/workdir/backend_state.go:116
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")
}
if stateFile.StateStore != nil && stateFile.StateStore.ProviderSupplyMode == "" {
// Check for this, as lacking this data can cause problems later when an empty provider version
// is encountered. This error will make debugging much easier.
return nil, fmt.Errorf("encountered a malformed backend state file with a 'state_store' block that is missing the required 'provider_supply_mode' property")
}
return &stateFile, nil
}
func EncodeBackendStateFile(f *BackendStateFile) ([]byte, error) {
f.Version = 3 // we only support version 3
f.TFVersion = version.SemVer.String()
switch {
case f.Backend != nil && f.StateStore != nil:
return nil, fmt.Errorf("attempted to encode a malformed backend state file; it contains state for both a 'backend' and a 'state_store' block. This is a bug in Terraform and should be reported.")
case f.Backend == nil && f.StateStore == nil:
// This is valid - if the user has a backend state file and an implied local backend in use
// the backend state file exists but has no Backend data.
case f.Backend != nil:
// Not implementing anything here - risk of breaking changes
case f.StateStore != nil:View on GitHub (pinned to c9def3e214)
Solutions
- Re-run 'terraform init' with a current Terraform release so the file is rewritten with provider_supply_mode populated.
- If editing by hand, set provider_supply_mode to the correct value for how the provider is installed (typically 'managed-by-terraform').
- If this recurs on a released Terraform, report it — the write path should always set the field.
Example fix
// before — .terraform/terraform.tfstate:
{ "version":3, "state_store":{ "type":"...", "provider":{...}, "config":{...}, "hash":0, "provider_supply_mode":"" } }
Error: ... missing the required 'provider_supply_mode' property
// after
{ "version":3, "state_store":{ ..., "provider_supply_mode":"managed-by-terraform" } }
// or: rm -rf .terraform && terraform init Defensive patterns
Strategy: validation
Validate before calling
// Ensure provider_supply_mode is set before encoding.
func stateStoreHasSupplyMode(s *StateStoreConfigState) bool {
return s != nil && s.ProviderSupplyMode != ""
} Type guard
null
Try / catch
null
Prevention
- Always populate ProviderSupplyMode when constructing a StateStoreConfigState programmatically.
- Use a released Terraform to write state_store files so the field is always set.
- Add a unit test that asserts every encoded state_store record has a non-empty supply mode.
When it happens
Trigger: ParseBackendStateFile finds StateStore != nil but StateStore.ProviderSupplyMode == '' (backend_state.go:113).
Common situations: A state_store file written by an early/buggy Terraform build that did not populate provider_supply_mode; manual editing that dropped the field; a half-completed migration.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to negotiate acceptable chunk size. Expected size > 0
- attempted to encode a malformed backend state file; it conta
- attempted to encode a malformed backend state file; provider
- state store is not valid: %w
- state store is not valid: provider version data is missing d
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/441bf995c0a5f7cd.
Report an issue: GitHub.