hashicorp/terraform · error
%s%s: cannot set both Optional and Required
Error message
%s%s: cannot set both Optional and Required
What it means
Raised when an Attribute has both Optional and Required set to true. These flags are mutually exclusive: Optional permits omission, Required forbids it — together they are contradictory. The validator at internal_validate.go:149 enforces exclusivity.
Source
Thrown at internal/configs/configschema/internal_validate.go:150
if a == nil {
return fmt.Errorf("attribute schema is nil")
}
return a.internalValidate(name, "")
}
func (a *Attribute) internalValidate(name, prefix string) error {
var err error
/* FIXME: this validation breaks certain existing providers and cannot be enforced without coordination.
if !validName.MatchString(name) {
err = errors.Join(err, fmt.Errorf("%s%s: name may contain only lowercase letters, digits and underscores", prefix, name))
}
*/
if !a.Optional && !a.Required && !a.Computed {
err = errors.Join(err, fmt.Errorf("%s%s: must set Optional, Required or Computed", prefix, name))
}
if a.Optional && a.Required {
err = errors.Join(err, fmt.Errorf("%s%s: cannot set both Optional and Required", prefix, name))
}
if a.Computed && a.Required {
err = errors.Join(err, fmt.Errorf("%s%s: cannot set both Computed and Required", prefix, name))
}
if !a.Deprecated && a.DeprecationMessage != "" {
err = errors.Join(err, fmt.Errorf("%s%s: DeprecationMessage must not be set when Deprecated is false", prefix, name))
}
if a.Type == cty.NilType && a.NestedType == nil {
err = errors.Join(err, fmt.Errorf("%s%s: either Type or NestedType must be defined", prefix, name))
}
if a.Type != cty.NilType {
if a.NestedType != nil {
err = errors.Join(fmt.Errorf("%s: Type and NestedType cannot both be set", name))
}
}
View on GitHub (pinned to c9def3e214)
Solutions
- Decide whether the user may omit the value: keep Optional (drop Required) or keep Required (drop Optional).
- If you want 'user may override a provider default', use Optional+Computed, not Optional+Required.
- Add a schema linter rule that rejects simultaneous Optional and Required.
Example fix
// before
"name": {Type: cty.String, Optional: true, Required: true}
// after
"name": {Type: cty.String, Required: true} Defensive patterns
Strategy: validation
Validate before calling
func assertNotOptionalAndRequired(a *configschema.Attribute) error {
if a.Optional && a.Required {
return fmt.Errorf("cannot set both Optional and Required")
}
return nil
} Type guard
func isMutuallyConsistent(a *configschema.Attribute) bool {
return !(a.Optional && a.Required)
} Prevention
- Treat Optional and Required as mutually exclusive radio buttons.
- For 'user may override a provider default', use Optional+Computed, not Optional+Required.
- Lint to reject attributes setting both flags.
When it happens
Trigger: An Attribute struct literal with both Optional: true and Required: true. internalValidate reaches line 149 and the condition holds.
Common situations: Copy-pasting an Optional attribute and adding Required without removing Optional; merging two schema fragments each setting a different flag; confusing 'Optional but with a default' with 'Required'.
Related errors
- %s%s: must set Optional, Required or Computed
- %s%s: cannot set both Computed and Required
- %s: Type and NestedType cannot both be set
- attribute schema is nil
- %s%s: either Type or NestedType must be defined
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/ac92ca919d5cd9de.
Report an issue: GitHub.