hashicorp/terraform · error
invalid value for in state
Error message
invalid value for %q in state: %s
What it means
Returned by hcl2ValueFromFlatmapPrimitive when the raw string stored in the flatmap cannot be converted to the declared attribute type via cty's convert.Convert. The shim first wraps the raw string as cty.StringVal then attempts a conversion; if conversion fails (e.g. the string is not parseable as the target number/bool/list), it reports the offending state key plus the underlying conversion error. As the comment notes, this only triggers for tampered/corrupt state — well-formed state always converts cleanly.
Solutions
- Inspect the state key named in the error and the conversion error message — the value is malformed for the declared type.
- Restore the attribute from a known-good state backup rather than editing it by hand.
- If the schema type legitimately changed, write a state upgrader that migrates the value before the new schema is applied.
- Avoid manual edits to .tfstate; use 'terraform state' subcommands or import flows instead.
Example fix
// not a code fix — operational recovery // before: state contains "size": "not-a-number" for a number-typed attribute // after: restore from backup, or run a state upgrader that casts the value
Defensive patterns
Strategy: validation
Validate before calling
// Caller-side: verify the raw flatmap string coerces to the target type before invoking the shim.
func canConvertFlatmapString(raw string, ty cty.Type) bool {
_, err := convert.Convert(cty.StringVal(raw), ty)
return err == nil
} Try / catch
if val, err := hcl2shim.HCL2ValueFromFlatmap(m, key, ty); err != nil {
// Distinguish corrupt state from a real bug: re-decode as string and surface
// a friendlier 'state value at <key> is malformed' message.
log.Printf("state decode failed for %q: %v; falling back to manual repair", key, err)
return repairOrAbort(key, err)
} Prevention
- Never hand-edit .tfstate files; use 'terraform state' subcommands instead.
- Take state backups before provider upgrades that tighten attribute types.
- Write a state upgrader when changing an attribute type so old state values are coerced before the new schema is applied.
When it happens
Trigger: Manually editing a state file and inserting a non-numeric string for an attribute whose schema type is number/bool; downgrading a provider whose new schema is stricter than the value persisted in state; restore of a state backup whose values were transformed by an external tool.
Common situations: Hand-edited .tfstate files; partial state corruption from disk failure or merge conflicts in remote state; switching a schema attribute from string to a stricter type while old state still holds incompatible values.
Related errors
- invalid count value for
- attribute not found
- cannot decode from flatmap
- index out of range in %#v
- invalid step with type %#v
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/d97ee9bafd5d6e59.
Report an issue: GitHub.
Appendix: source
Thrown at internal/configs/hcl2shim/flatmap.go:200
return val, nil
}
func hcl2ValueFromFlatmapPrimitive(m map[string]string, key string, ty cty.Type) (cty.Value, error) {
rawVal, exists := m[key]
if !exists {
return cty.NullVal(ty), nil
}
if rawVal == UnknownVariableValue {
return cty.UnknownVal(ty), nil
}
var err error
val := cty.StringVal(rawVal)
val, err = convert.Convert(val, ty)
if err != nil {
// This should never happen for _valid_ input, but flatmap data might
// be tampered with by the user and become invalid.
return cty.DynamicVal, fmt.Errorf("invalid value for %q in state: %s", key, err)
}
return val, nil
}
func hcl2ValueFromFlatmapObject(m map[string]string, prefix string, atys map[string]cty.Type) (cty.Value, error) {
vals := make(map[string]cty.Value)
for name, aty := range atys {
val, err := hcl2ValueFromFlatmapValue(m, prefix+name, aty)
if err != nil {
return cty.DynamicVal, err
}
vals[name] = val
}
return cty.ObjectVal(vals), nil
}
func hcl2ValueFromFlatmapTuple(m map[string]string, prefix string, etys []cty.Type) (cty.Value, error) {View on GitHub (pinned to d32a084675)