hashicorp/terraform · error

%s%s: MinItems and MaxItems must both be greater than zero

Error message

%s%s: MinItems and MaxItems must both be greater than zero

What it means

MinItems or MaxItems is negative (< 0, checked at line 64). The message wording ('must both be greater than zero') is slightly imprecise - the actual check only forbids negatives; zero is allowed and is the default meaning 'no limit'. It catches schemas that set, e.g., MinItems: -1 by mistake.

Source

Thrown at internal/configs/configschema/internal_validate.go:65

	}

	for name, blockS := range b.BlockTypes {
		if blockS == nil {
			multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: block schema is nil", prefix, name))
			continue
		}

		if _, isAttr := b.Attributes[name]; isAttr {
			multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: name defined as both attribute and child block type", prefix, name))
		} else if !validName.MatchString(name) {
			multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: name may contain only lowercase letters, digits and underscores", prefix, name))
		}
		if !blockS.Deprecated && blockS.DeprecationMessage != "" {
			multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: DeprecationMessage must not be set when Deprecated is false", prefix, name))
		}

		if blockS.MinItems < 0 || blockS.MaxItems < 0 {
			multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: MinItems and MaxItems must both be greater than zero", prefix, name))
		}

		// any nested blocks within a computed block must also be computed
		if b.Computed && !blockS.Computed {
			multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: all nested blocks within computed blocks must also be computed", prefix, name))
		}

		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))

View on GitHub (pinned to c9def3e214)

Solutions

  1. Set MinItems/MaxItems to 0 (no limit) or a positive integer.
  2. For 'required single', use NestingSingle with MinItems=MaxItems=1.

Example fix

// before
"items": {Nesting: configschema.NestingList, MinItems: -1, MaxItems: 0}

// after
"items": {Nesting: configschema.NestingList, MinItems: 0, MaxItems: 0}
Defensive patterns

Strategy: validation

Validate before calling

if nb.MinItems < 0 || nb.MaxItems < 0 {
    return fmt.Errorf("MinItems/MaxItems must not be negative")
}

Prevention

When it happens

Trigger: Assigning a sentinel like -1, an underflow, or a computed MinItems expression that yields a negative value.

Common situations: Trying to express 'optional' with -1, copying another field's value incorrectly, off-by-one bugs in schema generation.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/7ca1258dfd9ee0b7. Report an issue: GitHub.