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

  1. Remove RejectUnknowns from the MarshalOptions, or set KeepUnknowns: true so unknowns are serialized as sentinel values instead of erroring.
  2. Wait until the upstream output is known (move the logic out of preview, or run during update instead) before marshaling.
  3. Substitute a concrete value or placeholder for the computed property before marshaling (e.g. resource.NewProperty(defaultValue)).
  4. 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

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


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/0bd08658894d9d4c. Report an issue: GitHub.