{"record":{"id":"570d6ee762e5abb2","repo":"pulumi/pulumi","slug":"failed-to-save-snapshot-w","errorCode":null,"errorMessage":"failed to save snapshot: %w","messagePattern":"failed to save snapshot: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/backend/journal.go","lineNumber":547,"sourceCode":"\t// integrity error. This matches behaviour prior to when integrity metadata\n\t// writing was introduced.\n\t//\n\t// Metadata will be cleared out by a successful operation (even if integrity\n\t// checking is being enforced).\n\tintegrityError := snapshot.VerifyIntegrity(deployment.Deployment)\n\tif integrityError == nil {\n\t\tdeployment.Deployment.Metadata.IntegrityErrorMetadata = nil\n\t} else {\n\t\tdeployment.Deployment.Metadata.IntegrityErrorMetadata = &apitype.SnapshotIntegrityErrorMetadataV1{\n\t\t\tVersion: strconv.FormatInt(int64(deployment.Version), 10),\n\t\t\tCommand: strings.Join(os.Args, \" \"),\n\t\t\tError:   integrityError.Error(),\n\t\t\tEnvVars: utilenv.ConfiguredVariables(),\n\t\t}\n\t}\n\tpersister := sj.persister\n\tif err := persister.Save(deployment); err != nil {\n\t\treturn fmt.Errorf(\"failed to save snapshot: %w\", err)\n\t}\n\tif !DisableIntegrityChecking && integrityError != nil {\n\t\treturn fmt.Errorf(\"failed to verify snapshot: %w\", integrityError)\n\t}\n\treturn nil\n}\n\n// defaultServiceLoop saves a Snapshot whenever a mutation occurs\nfunc (sj *SnapshotJournaler) defaultServiceLoop(\n\tjournalEvents chan writeJournalEntryRequest, done chan error,\n) {\n\t// True if we have elided writes since the last actual write.\n\thasElidedWrites := true\n\n\t// Service each mutation request in turn.\nserviceLoop:\n\tfor {\n\t\tselect {","sourceCodeStart":529,"sourceCodeEnd":565,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/pkg/backend/journal.go#L529-L565","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-run the pulumi command — snapshot saving is retried per operation, and Pulumi checkpoints each step so re-running is safe","Verify authentication (`pulumi whoami`) and backend connectivity; for cloud backends check status.pulumi.com and PULUMI_ACCESS_TOKEN validity","For self-managed backends, verify bucket/file permissions and credentials (AWS/GCP/Azure session validity)","If snapshots are consistently too large, reduce state bloat (`pulumi refresh`, remove orphaned resources) or increase backend limits"],"exampleFix":"// before: expired cloud credentials cause Save to fail\n// after: re-authenticate before the operation\npulumi login\npulumi up","handlingStrategy":"retry","validationCode":"// before the operation, confirm write access to the backend\nwhoami, err := exec.Command(\"pulumi\", \"whoami\").Output()\nif err != nil || len(whoami) == 0 {\n    log.Fatal(\"cannot reach backend or token invalid; run `pulumi login`\")\n}","typeGuard":"func isSnapshotSaveErr(err error) bool {\n    return strings.Contains(err.Error(), \"failed to save snapshot:\")\n}","tryCatchPattern":"if err := saveSnapshot(); err != nil {\n    if strings.Contains(err.Error(), \"failed to save snapshot:\") {\n        time.Sleep(backoff)\n        return saveSnapshot() // idempotent per-operation checkpoint save\n    }\n    return err\n}","preventionTips":["Re-authenticate before long CI jobs (fresh PULUMI_ACCESS_TOKEN or OIDC)","Monitor backend status (status.pulumi.com) and cloud storage credentials","Keep snapshots lean (refresh + prune) to avoid size limits","Use per-step checkpointing: Pulumi saves each operation, so a failed save is recoverable by re-running"],"tags":["persistence","snapshot","backend","network"],"backgroundTag":"snapshot-save-failed","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}