hashicorp/terraform · error

: NestingSet attributes may not contain attributes of…

Error message

%s%s: NestingSet attributes may not contain attributes of cty.DynamicPseudoType

What it means

Thrown during schema validation when a NestingSet block's implied cty type contains DynamicPseudoType. HCL's set implementation must hash each element deterministically, which requires a fully-known element type; dynamic (union) element types cannot be hashed uniquely, so the configuration is rejected at validation time rather than producing silently wrong set semantics later.

Solutions

  1. Replace every cty.DynamicPseudoType attribute inside the NestingSet block with a concrete type (string, number, bool, object, etc.).
  2. If the values are genuinely heterogeneous, switch the nesting mode from NestingSet to NestingList (lists do not hash elements and tolerate dynamic types).
  3. If a JSON-blob-style field is needed, encode it as a single string-typed attribute (e.g. JSON-encoded) rather than a dynamic-typed one.
  4. Run InternalValidate() in provider unit tests to surface this at test time.

Example fix

// before
NestedType: &configschema.Object{
    Nesting: configschema.NestingSet,
    Attributes: map[string]*configschema.Attribute{
        "value": {Type: cty.DynamicPseudoType, Optional: true},
    },
}

// after — concrete type, or move to NestingList
NestedType: &configschema.Object{
    Nesting: configschema.NestingSet,
    Attributes: map[string]*configschema.Attribute{
        "value": {Type: cty.String, Optional: true},
    },
}
Defensive patterns

Strategy: validation

Validate before calling

func assertSetHasNoDynamic(o *configschema.Object) error {
    if o == nil || o.Nesting != configschema.NestingSet {
        return nil
    }
    for name, a := range o.Attributes {
        if a == nil { continue }
        if a.Type == cty.DynamicPseudoType {
            return fmt.Errorf("NestingSet attribute %q uses cty.DynamicPseudoType", name)
        }
        if err := assertSetHasNoDynamic(a.NestedType); err != nil { return err }
    }
    return nil
}

Type guard

func canHashElementType(o *configschema.Object) bool {
    if o == nil || o.Nesting != configschema.NestingSet { return true }
    ety := o.ImpliedType()
    return !ety.HasDynamicTypes()
}

Prevention

When it happens

Trigger: Defining a NestedType with Nesting: NestingSet where at least one nested attribute uses cty.DynamicPseudoType (or is omitted/optional in a way that yields a dynamic type), then invoking InternalValidate. Common when porting a list-of-dicts schema to a set and one attribute is left as a generic any/dynamic type.

Common situations: Provider schemas that accept arbitrary key/value metadata inside a set; mixing SDK v1 'Type' fields that map to cty.DynamicPseudoType inside a set block; upgrading a provider where a previously List-typed block is changed to Set without auditing dynamic-typed members.

Related errors


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

Appendix: source

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

	if a.Type != cty.NilType {
		if a.NestedType != nil {
			err = errors.Join(fmt.Errorf("%s: Type and NestedType cannot both be set", name))
		}
	}

	if a.NestedType != nil {
		switch a.NestedType.Nesting {
		case NestingSingle, NestingMap, NestingGroup:
			// no validations to perform
		case NestingList, NestingSet:
			if a.NestedType.Nesting == NestingSet {
				ety := a.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.
					err = errors.Join(err, fmt.Errorf("%s%s: NestingSet attributes may not contain attributes of cty.DynamicPseudoType", prefix, name))
				}
				if a.NestedType.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.
					err = errors.Join(err, fmt.Errorf("%s%s: NestingSet attributes may not contain WriteOnly attributes", prefix, name))
				}
			}
		default:
			err = errors.Join(err, fmt.Errorf("%s%s: invalid nesting mode %s", prefix, name, a.NestedType.Nesting))
		}
		for name, attrS := range a.NestedType.Attributes {
			if attrS == nil {
				err = errors.Join(err, fmt.Errorf("%s%s: attribute schema is nil", prefix, name))
				continue
			}
			err = errors.Join(err, attrS.internalValidate(name, prefix))
		}

View on GitHub (pinned to d32a084675)