hashicorp/terraform · error
%s%s: MinItems must be less than or equal to MaxItems in %s
Error message
%s%s: MinItems must be less than or equal to MaxItems in %s mode
What it means
Raised for NestingList or NestingSet blocks when MinItems exceeds MaxItems and MaxItems is non-zero. Cardinality bounds must form a valid range; an inverted range is a logical impossibility the validator refuses to serialize. The check lives at internal_validate.go:89 and includes the offending nesting mode in the message so the developer knows which block type tripped it.
Source
Thrown at internal/configs/configschema/internal_validate.go:90
switch blockS.Nesting {
case NestingSingle:
switch {
case blockS.MinItems != blockS.MaxItems:
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: MinItems and MaxItems must match in NestingSingle mode", prefix, name))
case blockS.MinItems < 0 || blockS.MinItems > 1:
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: MinItems and MaxItems must be set to either 0 or 1 in NestingSingle mode", prefix, name))
}
case NestingGroup:
if blockS.MinItems != 0 || blockS.MaxItems != 0 {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: MinItems and MaxItems cannot be used in NestingGroup mode", prefix, name))
}
if blockS.Computed {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: NestingGroup blocks cannot be computed", prefix, name))
}
case NestingList, NestingSet:
if blockS.MinItems > blockS.MaxItems && blockS.MaxItems != 0 {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: MinItems must be less than or equal to MaxItems in %s mode", prefix, name, blockS.Nesting))
}
if blockS.Nesting == NestingSet {
ety := blockS.Block.ImpliedType()
if ety.HasDynamicTypes() {
// This is not permitted because the HCL (cty) set implementation
// needs to know the exact type of set elements in order to
// properly hash them, and so can't support mixed types.
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: NestingSet blocks may not contain attributes of cty.DynamicPseudoType", prefix, name))
}
if blockS.Block.ContainsWriteOnly() {
// This is not permitted because any marks within sets will
// be hoisted up the outer set value, so only the set itself
// can be WriteOnly.
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: NestingSet blocks may not contain WriteOnly attributes", prefix, name))
}
}
if blockS.MinItems > 0 && blockS.Computed {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: Computed cannot be used when MinItems > 0", prefix, name))View on GitHub (pinned to c9def3e214)
Solutions
- Set MinItems to a value less than or equal to MaxItems (or set both to 0 for an unbounded list).
- If you intended a required minimum with no upper bound, leave MaxItems at 0 — the validator treats 0 as 'no upper limit'.
- Add a unit test that calls InternalValidate on the provider schema to catch inverted bounds before release.
Example fix
// before
&NestedBlock{Nesting: NestingList, MinItems: 5, MaxItems: 3}
// after
&NestedBlock{Nesting: NestingList, MinItems: 3, MaxItems: 5} Defensive patterns
Strategy: validation
Validate before calling
func assertCardinality(nb *configschema.NestedBlock) error {
if nb.MinItems > nb.MaxItems && nb.MaxItems != 0 {
return fmt.Errorf("MinItems (%d) must be <= MaxItems (%d)", nb.MinItems, nb.MaxItems)
}
return nil
} Prevention
- Treat MinItems/MaxItems as a pair: define them together in a helper that validates min<=max.
- Remember MaxItems==0 means 'no upper bound', not 'zero allowed' — use it for unbounded lists.
- Run InternalValidate in CI to catch inverted bounds before merge.
When it happens
Trigger: A NestedBlock with Nesting=NestingList (or NestingSet) where MinItems > MaxItems and MaxItems != 0 — e.g. MinItems: 5, MaxItems: 3. The validator enters the NestingList/NestingSet case at line 88 and fails the condition at line 89.
Common situations: Editing cardinality constants and swapping min/max values by mistake; generating schemas from a DSL where the lower/upper bounds were mapped to the wrong fields; copy-pasting a block and decrementing MaxItems below an inherited MinItems.
Related errors
- %s%s: Computed cannot be used when MinItems > 0
- %s%s: MinItems and MaxItems must both be 0 in NestingMap mod
- %s%s: NestingSet blocks may not contain attributes of cty.Dy
- %s%s: NestingSet blocks may not contain WriteOnly attributes
- %s%s: NestingSet attributes may not contain attributes of ct
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/9ec8ae085726fa69.
Report an issue: GitHub.