pulumi/pulumi · error
unmarshalling state: %w
Error message
unmarshalling state: %w
What it means
NewCloudSecretsManagerFromState reconstructs a cloud secrets manager from persisted JSON state. If the raw state cannot be unmarshalled into cloudSecretsManagerState (invalid JSON or wrong shape), this error wraps the failure. It's the read-path counterpart of the 'marshalling state' error at manager creation time.
Source
Thrown at pkg/secrets/cloud/manager.go:160
var s cloudSecretsManagerState
err := json.Unmarshal(state, &s)
if err != nil {
return fmt.Errorf("unmarshalling cloud state: %w", err)
}
info.SecretsProvider = s.URL
info.EncryptedKey = base64.StdEncoding.EncodeToString(s.EncryptedKey)
return nil
}
// NewCloudSecretsManagerFromState deserialize configuration from state and returns a secrets
// manager that uses the target cloud key management service to encrypt/decrypt a data key used for
// envelope encryption of secrets values.
func NewCloudSecretsManagerFromState(state json.RawMessage) (secrets.Manager, error) {
var s cloudSecretsManagerState
err := json.Unmarshal(state, &s)
if err != nil {
return nil, fmt.Errorf("unmarshalling state: %w", err)
}
// We're emulating gocloud.dev's old behaviour here. Pre v0.28.0 it used to have an inner wrapping, which
// we keep for compatibility (see above). However the newer version expects this to be unwrapped, before
// it's used. newCloudSecretsManager will manage that but we need to check here as well to handle the
// #15329 regression.
dataKey := s.EncryptedKey
if strings.HasPrefix(s.URL, "azurekeyvault://") {
wrappedKey, err := base64.RawURLEncoding.DecodeString(string(dataKey))
if err != nil {
// https://github.com/pulumi/pulumi/issues/15329 resulted in some non-encoded keys being written
// to state. This checks that case to see if there valid base64 data.
firstErr := err
_, err := base64.StdEncoding.DecodeString(string(wrappedKey))
if err != nil {
// Wasn't valid base64 so probably just gibberish, return the first error we saw.
return nil, firstErr
}View on GitHub (pinned to 793f7b2e16)
Solutions
- Restore Pulumi.<stack>.yaml (or the state blob) from version control or backup.
- Re-initialize the secrets provider: `pulumi stack change-secrets-provider <new-provider>` (note existing secrets must be re-entered if the data key is lost).
- Check the state matches {"url":"...","encryptedkey":"base64..."} shape and fix formatting.
- Verify you are not passing a passphrase-style salt string into the cloud manager constructor.
Example fix
// before
NewCloudSecretsManagerFromState(json.RawMessage("v1:salt:...")) // wrong provider state
// after
NewCloudSecretsManagerFromState(json.RawMessage(`{"url":"gcpkms://...","encryptedkey":"BASE64=="}`)) Defensive patterns
Strategy: validation
Validate before calling
func isValidCloudSecretsState(state json.RawMessage) bool {
var s struct {
URL string `json:"url"`
EncryptedKey []byte `json:"encryptedkey"`
}
return json.Unmarshal(state, &s) == nil && strings.Contains(s.URL, "://")
}
// only call NewCloudSecretsManagerFromState when isValidCloudSecretsState(state) Type guard
func parseCloudState(state json.RawMessage) (*cloudSecretsManagerState, bool) {
var s cloudSecretsManagerState
if err := json.Unmarshal(state, &s); err != nil {
return nil, false
}
return &s, true
} Try / catch
mgr, err := NewCloudSecretsManagerFromState(state)
if err != nil {
if strings.Contains(err.Error(), "unmarshalling state") {
return nil, fmt.Errorf("stack secrets state corrupt; restore Pulumi.<stack>.yaml or run 'pulumi stack change-secrets-provider': %w", err)
}
return nil, err
} Prevention
- Version-control Pulumi.<stack>.yaml so corrupt state can be restored.
- Don't mix state blobs between different secrets-provider types.
- Use `pulumi stack change-secrets-provider` for provider migrations instead of manual edits.
- Back up stack config before upgrading CLI versions.
When it happens
Trigger: Loading a stack whose persisted secrets-manager state is corrupt, truncated, manually edited, or produced by an incompatible provider (e.g. passphrase salt text instead of the cloud state JSON).
Common situations: Hand-edited Pulumi.<stack>.yaml; git merge conflicts in stack config; migrating stacks between secrets providers; restoring partial backups; bug #15329-style regressions around the wrapped/unwrapped encrypted-key format.
Related errors
- unmarshalling cloud state: %w
- unmarshalling passphrase state: %w
- failed to unmarshal stack tags: %w
- unmarshalling response object: %w
- value for --json object key %q is nil
AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31).
Data as JSON: /api/errors/4051eeb2fe85471b.
Report an issue: GitHub.