hashicorp/terraform · error
%s%s: NestingSet blocks may not contain WriteOnly attributes
Error message
%s%s: NestingSet blocks may not contain WriteOnly attributes
What it means
Raised when a NestingSet block transitively contains a WriteOnly attribute. WriteOnly marks are hoisted by cty up to the enclosing set value, so per-element WriteOnly flags would be lost or misapplied; only the set-level attribute itself may be WriteOnly. The check at internal_validate.go:100 calls blockS.Block.ContainsWriteOnly() and rejects the schema.
Source
Thrown at internal/configs/configschema/internal_validate.go:104
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))
}
case NestingMap:
if blockS.MinItems != 0 || blockS.MaxItems != 0 {
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: MinItems and MaxItems must both be 0 in NestingMap mode", 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))
}
default:
multiErr = errors.Join(multiErr, fmt.Errorf("%s%s: invalid nesting mode %s", prefix, name, blockS.Nesting))
}
subPrefix := prefix + name + "."
multiErr = errors.Join(multiErr, blockS.Block.internalValidate(subPrefix))View on GitHub (pinned to c9def3e214)
Solutions
- Move the WriteOnly flag off the inner attribute and onto the enclosing set attribute, or remove it entirely if the data is persisted.
- Change the block from NestingSet to NestingList, which permits inner WriteOnly attributes.
- If individual elements must remain ephemeral, model the collection as a NestingList of single-field objects rather than a set.
Example fix
// before
BlockTypes: map[string]*NestedBlock{
"peer": {Nesting: NestingSet, Block: Block{Attributes: map[string]*Attribute{
"token": {Type: cty.String, Optional: true, WriteOnly: true},
}}},
}
// after
BlockTypes: map[string]*NestedBlock{
"peer": {Nesting: NestingList, Block: Block{Attributes: map[string]*Attribute{
"token": {Type: cty.String, Optional: true, WriteOnly: true},
}}},
} Defensive patterns
Strategy: validation
Validate before calling
func assertSetBlockNoWriteOnly(nb *configschema.NestedBlock) error {
if nb.Nesting != configschema.NestingSet { return nil }
if nb.Block.ContainsWriteOnly() {
return fmt.Errorf("NestingSet block may not contain WriteOnly attributes")
}
return nil
} Prevention
- Only the outer set-level attribute may carry WriteOnly; never inner elements.
- Use NestingList when individual elements must be ephemeral.
- Audit secret-bearing fields whenever converting a list to a set.
When it happens
Trigger: A NestedBlock with Nesting=NestingSet whose descendant Attributes include one with WriteOnly: true. The NestingSet branch at line 92 evaluates ContainsWriteOnly() at line 100 and it returns true.
Common situations: Adding a sensitive ephemeral credential field (WriteOnly) to a set-valued block such as a list of upstream peers; converting a NestingList of credentials to NestingSet without removing inner WriteOnly flags; schema generation that marks all secret-looking fields WriteOnly by default.
Related errors
- %s%s: NestingSet attributes may not contain WriteOnly attrib
- %s%s: MinItems must be less than or equal to MaxItems in %s
- %s%s: NestingSet blocks may not contain attributes of cty.Dy
- %s%s: Computed cannot be used when MinItems > 0
- %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/8434b7a421be6bc2.
Report an issue: GitHub.