pulumi/pulumi · error
unexpected unknown property value for %q
Error message
unexpected unknown property value for %q
What it means
During RPC marshaling of a Pulumi property value (MarshalPropertyValue), the value is a Computed/unknown, and MarshalOptions.RejectUnknowns is set, so the marshaler refuses to serialize it and returns this error naming the property key. The Pulumi engine normally swallows unknowns (returns nil), but RejectUnknowns is used by callers that require fully-resolved values, e.g. when a provider must never send unresolved outputs across the wire.
Source
Thrown at sdk/go/common/resource/plugin/rpc.go:192
} else if v.IsAsset() {
if opts.RejectAssets {
return nil, fmt.Errorf("unexpected Asset property value for %q", key)
}
return MarshalAsset(v.AssetValue(), opts)
} else if v.IsArchive() {
if opts.RejectAssets {
return nil, fmt.Errorf("unexpected Asset Archive property value for %q", key)
}
return MarshalArchive(v.ArchiveValue(), opts)
} else if v.IsObject() {
obj, err := MarshalProperties(v.ObjectValue(), opts)
if err != nil {
return nil, err
}
return MarshalStruct(obj, opts), nil
} else if v.IsComputed() {
if opts.RejectUnknowns {
return nil, fmt.Errorf("unexpected unknown property value for %q", key)
} else if opts.KeepUnknowns {
if opts.KeepOutputValues && opts.UpgradeToOutputValues {
output := resource.NewProperty(resource.PropertyMap{
resource.SigKey: resource.NewProperty(resource.OutputValueSig),
})
return MarshalPropertyValue(key, output, opts)
}
return marshalUnknownProperty(v.Input().Element, opts), nil
}
return nil, nil // return nil and the caller will ignore it.
} else if v.IsOutput() {
if !opts.KeepOutputValues {
result := v.OutputValue().Element
if !v.OutputValue().Known {
// Unknown outputs are marshaled the same as Computed.
result = resource.MakeComputed(resource.NewProperty(""))
}
if v.OutputValue().Secret {View on GitHub (pinned to 793f7b2e16)
Solutions
- Remove RejectUnknowns from the MarshalOptions, or set KeepUnknowns: true so unknowns are serialized as sentinel values instead of erroring.
- Wait until the upstream output is known (move the logic out of preview, or run during update instead) before marshaling.
- Substitute a concrete value or placeholder for the computed property before marshaling (e.g. resource.NewProperty(defaultValue)).
- Filter the PropertyMap to drop Computed values before calling MarshalProperties.
Example fix
// before
props := resource.NewPropertyMapFromMap(map[string]interface{}{"bucket": bucket.BucketName()}) // output, unknown in preview
out, err := plugin.MarshalProperties(props, plugin.MarshalOptions{RejectUnknowns: true})
// after
out, err := plugin.MarshalProperties(props, plugin.MarshalOptions{KeepUnknowns: true}) Defensive patterns
Strategy: validation
Validate before calling
// Drop or flag unknowns before marshaling
func stripUnknowns(m resource.PropertyMap) resource.PropertyMap {
out := resource.PropertyMap{}
for k, v := range m {
if !v.IsComputed() && !(v.IsOutput() && !v.OutputValue().Known) {
out[k] = v
}
}
return out
}
// if len(out) != len(m): an unknown was present — resolve it or use KeepUnknowns:true Type guard
func isUnknown(v resource.PropertyValue) bool {
return v.IsComputed() || (v.IsOutput() && !v.OutputValue().Known)
} Prevention
- Never enable RejectUnknowns on marshal paths that can run during preview, when outputs are unresolved.
- Prefer KeepUnknowns: true so unknowns round-trip as sentinels instead of failing.
- Check properties with IsComputed/OutputValue().Known before marshaling strict payloads.
- Add a unit test that round-trips a map containing MakeComputed to catch option regressions.
When it happens
Trigger: Calling MarshalProperties/MarshalPropertyValue with MarshalOptions{RejectUnknowns: true} on a PropertyMap that contains resource.MakeComputed(...) values, or an OutputValue with Known=false while KeepUnknowns is false. Typical call sites: check/Update RPCs configured to reject unknowns, or provider/plugin code that manually marshals inputs containing unresolved outputs.
Common situations: A developer passes a resource output (still unknown during preview) into a config bag or provider argument that is marshaled with strict options; an SDK upgrade changes default marshal options so unknowns that were previously dropped now fail; custom provider code builds inputs from outputs of resources not yet created (preview phase).
Related errors
- the builtin provider does not support List
- unknown property "%v"
- stack reference can not be imported
- stash can not be imported
- builtin resources may not be constructed
AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31).
Data as JSON: /api/errors/0bd08658894d9d4c.
Report an issue: GitHub.