hashicorp/terraform · error
: attribute schema is nil
Error message
%s%s: attribute schema is nil
What it means
During schema validation, an entry in the Block's Attributes map has a nil value. Every attribute name must map to a non-nil *Attribute schema. A nil attribute pointer indicates a programming error in schema construction — a developer added an attribute key but never populated its schema definition.
Solutions
- Audit the provider's schema construction code for the resource or data source named in the error.
- Ensure every key in the Attributes map maps to a fully populated *configschema.Attribute (or schema.Attribute in the framework).
- If using conditional attribute inclusion, use a filter step that removes keys entirely rather than setting them to nil.
- Add unit tests calling InternalValidate() on the schema to catch this before release.
Example fix
// before — nil attribute value in map
Attributes: map[string]*Attribute{
"name": {Type: String, Optional: true},
"size": nil, // ← bug
}
// after — all attributes populated or omitted
Attributes: map[string]*Attribute{
"name": {Type: String, Optional: true},
"size": {Type: Int, Optional: true},
} Defensive patterns
Strategy: validation
Validate before calling
// Provider developers: ensure no nil attribute values in schema
func sanitizeAttributeMap(attrs map[string]*configschema.Attribute) map[string]*configschema.Attribute {
clean := make(map[string]*configschema.Attribute, len(attrs))
for k, v := range attrs {
if v == nil {
log.Printf("WARN: attribute %q has nil schema, removing", k)
continue
}
clean[k] = v
}
return clean
}
// Unit test gate:
func TestNoNilAttributes(t *testing.T) {
if err := myResourceSchema().InternalValidate(); err != nil {
t.Fatal(err)
}
} Prevention
- Never add a key to the Attributes map without a fully populated *Attribute value.
- Use conditional omission (skip the key) rather than nil assignment.
- Gate every schema change behind an InternalValidate() unit test.
When it happens
Trigger: Block.Attributes map contains a key mapped to nil. Triggered when a provider (or Terraform internal code) constructs a schema with an incompletely initialized Attributes map — e.g., assigning attributes["foo"] = nil instead of a populated *Attribute struct.
Common situations: Provider developer uses a map literal or loop that conditionally leaves entries nil. Schema generation tool produces incomplete output. terraform-plugin-sdk/schema-to-framework migration left gaps. Code path that adds attribute keys dynamically but skips some values.
Related errors
- : all attributes within computed blocks must also be…
- : block schema is nil
- top-level block schema is nil
- : name defined as both attribute and child block type
- : name may contain only lowercase letters, digits and…
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/cc71a4d74560f7a0.
Report an issue: GitHub.
Appendix: 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 d32a084675)