pulumi/pulumi · critical

failed to save snapshot: %w

Error message

failed to save snapshot: %w

What it means

After a deployment snapshot is successfully created, saveSnapshot hands it to the configured persister (backend-specific snapshot write, e.g. cloud API or blob store). 'failed to save snapshot: %w' wraps any error from persister.Save(deployment), meaning the snapshot was built fine but could not be durably stored — the operation's state changes may be lost or need re-applying.

Source

Thrown at pkg/backend/journal.go:547

	// integrity error. This matches behaviour prior to when integrity metadata
	// writing was introduced.
	//
	// Metadata will be cleared out by a successful operation (even if integrity
	// checking is being enforced).
	integrityError := snapshot.VerifyIntegrity(deployment.Deployment)
	if integrityError == nil {
		deployment.Deployment.Metadata.IntegrityErrorMetadata = nil
	} else {
		deployment.Deployment.Metadata.IntegrityErrorMetadata = &apitype.SnapshotIntegrityErrorMetadataV1{
			Version: strconv.FormatInt(int64(deployment.Version), 10),
			Command: strings.Join(os.Args, " "),
			Error:   integrityError.Error(),
			EnvVars: utilenv.ConfiguredVariables(),
		}
	}
	persister := sj.persister
	if err := persister.Save(deployment); err != nil {
		return fmt.Errorf("failed to save snapshot: %w", err)
	}
	if !DisableIntegrityChecking && integrityError != nil {
		return fmt.Errorf("failed to verify snapshot: %w", integrityError)
	}
	return nil
}

// defaultServiceLoop saves a Snapshot whenever a mutation occurs
func (sj *SnapshotJournaler) defaultServiceLoop(
	journalEvents chan writeJournalEntryRequest, done chan error,
) {
	// True if we have elided writes since the last actual write.
	hasElidedWrites := true

	// Service each mutation request in turn.
serviceLoop:
	for {
		select {

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Re-run the pulumi command — snapshot saving is retried per operation, and Pulumi checkpoints each step so re-running is safe
  2. Verify authentication (`pulumi whoami`) and backend connectivity; for cloud backends check status.pulumi.com and PULUMI_ACCESS_TOKEN validity
  3. For self-managed backends, verify bucket/file permissions and credentials (AWS/GCP/Azure session validity)
  4. If snapshots are consistently too large, reduce state bloat (`pulumi refresh`, remove orphaned resources) or increase backend limits

Example fix

// before: expired cloud credentials cause Save to fail
// after: re-authenticate before the operation
pulumi login
pulumi up
Defensive patterns

Strategy: retry

Validate before calling

// before the operation, confirm write access to the backend
whoami, err := exec.Command("pulumi", "whoami").Output()
if err != nil || len(whoami) == 0 {
    log.Fatal("cannot reach backend or token invalid; run `pulumi login`")
}

Type guard

func isSnapshotSaveErr(err error) bool {
    return strings.Contains(err.Error(), "failed to save snapshot:")
}

Try / catch

if err := saveSnapshot(); err != nil {
    if strings.Contains(err.Error(), "failed to save snapshot:") {
        time.Sleep(backoff)
        return saveSnapshot() // idempotent per-operation checkpoint save
    }
    return err
}

Prevention

When it happens

Trigger: persister.Save(deployment) returns an error during saveSnapshot, triggered by defaultServiceLoop/unsafeServiceLoop — network failure to the Pulumi service, auth/permission rejection, storage backend outage, or payload too large.

Common situations: Pulumi Cloud 4xx/5xx (expired token, org permission changes); local/object-store backend (s3://, file://) credentials or connectivity problems; very large snapshots exceeding backend size limits; transient network drops mid-write.

Related errors


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