pulumi/pulumi · error

marshaling state migration request: %w

Error message

marshaling state migration request: %w

What it means

The engine failed to proto.Marshal a pulumirpc.StateMigrationRequest (URN + old state bytes) before invoking the state-migration callback. This request carries a provider's legacy state for migration; an encoding failure here aborts the migration path.

Source

Thrown at pkg/resource/deploy/source_eval.go:1673

// Wrap the state migration callback so the engine can call the callback server, which will then execute the
// function.  The wrapper takes care of all the necessary marshalling and unmarshalling.
func (rm *resmon) wrapStateMigrationCallback(cb *pulumirpc.Callback) (StateMigrationFunction, error) {
	client, err := rm.GetCallbacksClient(cb.Target)
	if err != nil {
		return nil, err
	}

	token := cb.Token
	return func(ctx context.Context, urn resource.URN, oldState []byte) ([]byte, map[resource.URN]resource.URN, error) {
		logging.V(5).Infof("StateMigration: urn=%v", urn)

		request, err := proto.Marshal(&pulumirpc.StateMigrationRequest{
			Urn:      string(urn),
			OldState: oldState,
		})
		if err != nil {
			return nil, nil, fmt.Errorf("marshaling state migration request: %w", err)
		}

		resp, err := client.Invoke(ctx, &pulumirpc.CallbackInvokeRequest{
			Token:   token,
			Request: request,
		})
		if err != nil {
			logging.V(5).Infof("state migration callback error: %v", err)
			return nil, nil, err
		}

		var response pulumirpc.StateMigrationResponse
		if err := proto.Unmarshal(resp.Response, &response); err != nil {
			return nil, nil, fmt.Errorf("unmarshaling state migration response: %w", err)
		}

		successors := make(map[resource.URN]resource.URN, len(response.Successors))
		for oldURN, newURN := range response.Successors {

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Upgrade the Pulumi CLI to the latest version (engine-level encoding bug).
  2. Check the oldState payload size; very large legacy state may need manual stack export/import migration instead.
  3. If you develop the provider, ensure OldState is populated with valid bytes before requesting migration.
  4. File a Pulumi issue with the URN and error.
Defensive patterns

Strategy: try-catch

Validate before calling

// Guard before requesting migration
if len(oldState) == 0 || len(oldState) > 32*1024*1024 {
	return nil, nil, fmt.Errorf("oldState invalid or too large (%d bytes): migrate via stack export/import", len(oldState))
}

Try / catch

request, err := proto.Marshal(&pulumirpc.StateMigrationRequest{...})
if err != nil {
	// fall back: surface URN so operator can migrate manually
	return nil, nil, fmt.Errorf("state migration unavailable for %s: %w", urn, err)
}

Prevention

When it happens

Trigger: A resource whose provider signals a state migration (legacy pre-2.0 style state) triggers the migration callback path and proto.Marshal of the request fails at source_eval.go:1673, typically due to nil oldState or a message exceeding proto size limits.

Common situations: Migrating very old stacks where OldState was populated with nil/oversized payloads; version skew in patched engine builds; extremely large legacy state blobs.

Related errors


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