hashicorp/terraform · error
invalid md5
Error message
invalid md5
What it means
Computed and Required are mutually exclusive on an Attribute. Required forces the user to supply the value, while Computed means the provider supplies it — the combination is contradictory. Note that Computed+Optional is permitted (user may override a provider-supplied default).
Solutions
- If the provider supplies the value but the user may override, use Optional: true, Computed: true (drop Required).
- If the user must always set it, drop Computed and keep Required.
Example fix
// before
"region": { Type: cty.String, Required: true, Computed: true },
// after
"region": { Type: cty.String, Optional: true, Computed: true }, Defensive patterns
Strategy: validation
Validate before calling
// Computed and Required are mutually exclusive.
func notComputedAndRequired(a *configschema.Attribute) bool {
return a == nil || !(a.Computed && a.Required)
} Type guard
func notBoth(computed, required bool) bool { return !(computed && required) } Prevention
- Drop Required when you add Computed; use Optional+Computed for overrides.
- Treat Required+Computed as a schema smell and reject it in review.
- Lint flag combinations in CI.
When it happens
Trigger: An Attribute with both Computed: true and Required: true. Guard at internal_validate.go:152 is `a.Computed && a.Required`.
Common situations: Marking a previously-required attribute as Computed without clearing Required; misunderstanding and thinking Computed+Required means 'provider fills if user omits'.
Related errors
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/f9b968d29348d949.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/s3/client.go:621
TableName: aws.String(c.ddbTable),
ConsistentRead: aws.Bool(true),
}
resp, err := c.dynClient.GetItem(ctx, getParams)
if err != nil {
return nil, fmt.Errorf("Unable to retrieve item from DynamoDB table %q: %w", c.ddbTable, err)
}
var val string
if v, ok := resp.Item["Digest"]; ok {
if v, ok := v.(*dynamodbtypes.AttributeValueMemberS); ok {
val = v.Value
}
}
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 so that clients can check for stale state files.
func (c *RemoteClient) putMD5(ctx context.Context, sum []byte) error {
if c.ddbTable == "" {
return nil
}
if len(sum) != md5.Size {
return errors.New("invalid payload md5")
}
putParams := &dynamodb.PutItemInput{
Item: map[string]dynamodbtypes.AttributeValue{
"LockID": &dynamodbtypes.AttributeValueMemberS{View on GitHub (pinned to d32a084675)