hashicorp/terraform · error
invalid md5
Error message
invalid md5
What it means
An Attribute must declare at least one of Optional, Required, or Computed — otherwise Terraform cannot decide whether the value comes from config, the provider, or both. The validator treats an attribute with all three false as ill-defined.
Solutions
- Mark the attribute Optional if the user may set it (optionally overridden by the provider).
- Mark it Required if the user must set it.
- Mark it Computed if only the provider supplies it (typically also Optional to allow overrides).
Example fix
// before
"name": { Type: cty.String },
// after
"name": { Type: cty.String, Optional: true, Computed: true }, Defensive patterns
Strategy: validation
Validate before calling
// Require at least one of Optional, Required, Computed.
func hasBehaviorFlag(a *configschema.Attribute) bool {
return a != nil && (a.Optional || a.Required || a.Computed)
} Type guard
func hasAtLeastOneBehavior(optional, required, computed bool) bool {
return optional || required || computed
} Prevention
- Always set at least one behavior flag when authoring an attribute.
- Use Optional+Computed for provider-overridable defaults.
- Lint schemas to reject behavior-less attributes.
When it happens
Trigger: An Attribute literal that sets Type but omits Optional/Required/Computed. Guard at internal_validate.go:146 is `!a.Optional && !a.Required && !a.Computed`.
Common situations: Forgetting the behavior flags when focusing on the type; schema codegen that emits the type only; copy-paste that drops the flags.
Related errors
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/3329deff1de5df34.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/oss/client.go:247
log.Printf("[DEBUG] Retrieving state serial in tablestore: %#v", getParams)
object, err := c.otsClient.GetRow(&tablestore.GetRowRequest{
SingleRowQueryCriteria: getParams,
})
if err != nil {
return nil, err
}
var val string
if v, ok := object.GetColumnMap().Columns["Digest"]; ok && len(v) > 0 {
val = v[0].Value.(string)
}
sum, err := hex.DecodeString(val)
if err != nil || len(sum) != md5.Size {
return nil, errors.New("invalid md5")
}
return sum, nil
}
// store the hash of the state to that clients can check for stale state files.
func (c *RemoteClient) putMD5(sum []byte) error {
if c.otsTable == "" {
return nil
}
if len(sum) != md5.Size {
return errors.New("invalid payload md5")
}
putParams := &tablestore.PutRowChange{
TableName: c.otsTable,
PrimaryKey: &tablestore.PrimaryKey{View on GitHub (pinned to d32a084675)