hashicorp/terraform · error

%s%s: attribute schema is nil

Error message

%s%s: attribute schema is nil

What it means

A nil entry exists in a Block's Attributes map (b.Attributes[name] == nil, checked at line 37). The validator cannot recurse into a nil attribute, so it records the error and `continue`s with other attributes. Indicates a schema map built with an explicit nil value, usually a typo or an unfilled placeholder.

Source

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

// This can be used within unit tests to detect when a given schema is invalid,
// and is run when terraform loads provider schemas during NewContext.
func (b *Block) InternalValidate() error {
	if b == nil {
		return fmt.Errorf("top-level block schema is nil")
	}
	return b.internalValidate("")
}

func (b *Block) internalValidate(prefix string) error {
	var multiErr error

	if prefix == "" && !b.Deprecated && b.DeprecationMessage != "" {
		multiErr = errors.Join(multiErr, fmt.Errorf("top-level block: DeprecationMessage must not be set when Deprecated is false"))
	}

	for name, attrS := range b.Attributes {
		if attrS == nil {
			multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: attribute schema is nil", prefix, name))
			continue
		}
		multiErr = errors.Join(multiErr, attrS.internalValidate(name, prefix))

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

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

View on GitHub (pinned to c9def3e214)

Solutions

  1. Ensure every map value is a fully-populated *Attribute.
  2. Guard builders: only insert when the attribute is non-nil.
  3. Run InternalValidate in tests to catch it before release.

Example fix

// before
Attributes: map[string]*configschema.Attribute{
    "name": nil,
}

// after
Attributes: map[string]*configschema.Attribute{
    "name": {Type: cty.String, Optional: true},
}
Defensive patterns

Strategy: validation

Validate before calling

// Strip/flag nil attributes when building a schema map.
for k, v := range attrs {
    if v == nil { return fmt.Errorf("attribute %q is nil", k) }
}

Prevention

When it happens

Trigger: Constructing Attributes with `"foo": nil`, appending a pointer that was never assigned, or a helper returning nil that gets stored directly (e.g. `attrs[name] = maybeAttr()` where maybeAttr returns nil).

Common situations: Schema builders with conditional attributes, refactor leftovers, generated schemas with an empty slot.

Related errors


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