{"record":{"id":"d5ce3420a12e2e8e","repo":"kopia/kopia","slug":"unable-to-run-maintenance","errorCode":null,"errorMessage":"unable to run maintenance","messagePattern":"unable to run maintenance","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/server/server.go","lineNumber":1007,"sourceCode":"\n\tdefer s.endUpload(ctx, src, &result)\n\n\terr := errors.Wrap(s.taskmgr.Run(\n\t\tctx,\n\t\t\"Snapshot\",\n\t\tfmt.Sprintf(\"%v at %v\", src, clock.Now().Format(time.RFC3339)),\n\t\tfunc(ctx context.Context, ctrl uitask.Controller) error {\n\t\t\treturn inner(ctx, ctrl, &result)\n\t\t}), \"snapshot task\")\n\tif err != nil {\n\t\tresult.Error = err.Error()\n\t}\n\n\treturn err\n}\n\nfunc (s *Server) runMaintenanceTask(ctx context.Context, dr repo.DirectRepository) error {\n\treturn errors.Wrap(s.taskmgr.Run(ctx, \"Maintenance\", \"Periodic maintenance\", func(ctx context.Context, _ uitask.Controller) error {\n\t\treturn repo.DirectWriteSession(ctx, dr, repo.WriteSessionOptions{\n\t\t\tPurpose: \"periodicMaintenance\",\n\t\t}, func(ctx context.Context, w repo.DirectRepositoryWriter) error {\n\t\t\treturn snapshotmaintenance.Run(ctx, w, maintenance.ModeAuto, false, maintenance.SafetyFull)\n\t\t})\n\t}), \"unable to run maintenance\")\n}\n\n// +checklocksread:s.serverMutex\nfunc (s *Server) isLocal(src snapshot.SourceInfo) bool {\n\treturn s.rep.ClientOptions().Hostname == src.Host && !s.rep.ClientOptions().ReadOnly\n}\n\nfunc (s *Server) getOrCreateSourceManager(ctx context.Context, src snapshot.SourceInfo) *sourceManager {\n\ts.serverMutex.Lock()\n\tdefer s.serverMutex.Unlock()\n\n\tif s.sourceManagers[src] == nil {","sourceCodeStart":989,"sourceCodeEnd":1025,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/internal/server/server.go#L989-L1025","documentation":"The server's periodic maintenance task wraps repo.DirectWriteSession + snapshotmaintenance.Run in a taskmgr task; any failure is wrapped as 'unable to run maintenance'. Maintenance handles garbage collection, blob retention, and content rewriting, so failures here can let deleted data accumulate but don't corrupt existing snapshots.","triggerScenarios":"DirectWriteSession cannot get a write lock on the repository (another client holds it); maintenance run by another client conflicts; underlying storage errors during GC/rewrite; context cancellation when the server shuts down mid-run.","commonSituations":"Another host/client is running maintenance simultaneously (exclusive lock contention); read-only storage backend; blob storage throttling/errors during long GC passes; server shutdown interrupting maintenance.","solutions":["Check the wrapped error for lock contention and ensure no other client is running maintenance at the same interval.","Run `kopia maintenance run` manually on one designated client to see and fix the underlying error.","Verify the storage backend is writable and not rate-limiting during maintenance operations.","Increase maintenance scheduling interval or ensure the server stays up long enough for full maintenance to finish."],"exampleFix":"// before\n// two hosts both run auto maintenance -> lock contention\n// after\n// on secondary clients:\nkopia maintenance set-owner --maybe-perform-quick-maintenance=false <client-id>\n// keep periodic maintenance on the server host only","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := s.runMaintenanceTask(ctx, dr)\nif err != nil {\n\t// lock contention is transient: reschedule rather than fail hard\n\tif strings.Contains(err.Error(), \"unable to obtain lock\") { scheduleRetry() }\n}","preventionTips":["Designate a single maintenance owner (maintenance set-owner) to avoid contention","Schedule maintenance during idle windows and keep the server alive long enough to finish","Ensure the storage backend is writable and not rate-limited during maintenance"],"tags":["maintenance","gc","kopia","task"],"backgroundTag":"database-write-failed","analyzedSha":"82495e54b584c1ef6073c9e1be048f57f8aef078","analyzedAt":"2026-09-07T20:35:21.689Z","contentChangedAt":"2026-09-07T20:35:21.689Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}