{"record":{"id":"be4f994aaea36e1d","repo":"dgraph-io/dgraph","slug":"cannot-start-backup-operation","errorCode":null,"errorMessage":"cannot start backup operation","messagePattern":"cannot start backup operation","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"worker/backup.go","lineNumber":195,"sourceCode":"\tglog.Infof(\"Backup request: group %d at %d\", req.GroupId, req.ReadTs)\n\tif err := ctx.Err(); err != nil {\n\t\tglog.Errorf(\"Context error during backup: %v\\n\", err)\n\t\treturn nil, err\n\t}\n\n\tg := groups()\n\tif g.groupId() != req.GroupId {\n\t\treturn nil, errors.Errorf(\"Backup request group mismatch. Mine: %d. Requested: %d\\n\",\n\t\t\tg.groupId(), req.GroupId)\n\t}\n\n\tif err := posting.Oracle().WaitForTs(ctx, req.ReadTs); err != nil {\n\t\treturn nil, err\n\t}\n\n\tcloser, err := g.Node.startTaskAtTs(opBackup, req.ReadTs)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"cannot start backup operation\")\n\t}\n\tdefer closer.Done()\n\n\tbp := NewBackupProcessor(pstore, req)\n\tdefer bp.Close()\n\n\treturn bp.WriteBackup(closer.Ctx())\n}\n\n// BackupGroup backs up the group specified in the backup request.\nfunc BackupGroup(ctx context.Context, in *pb.BackupRequest) (*pb.BackupResponse, error) {\n\tglog.V(2).Infof(\"Sending backup request: %+v\\n\", in)\n\tif groups().groupId() == in.GroupId {\n\t\treturn backupCurrentGroup(ctx, in)\n\t}\n\n\t// This node is not part of the requested group, send the request over the network.\n\tpl := groups().AnyServer(in.GroupId)","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/worker/backup.go#L177-L213","documentation":"Before running a backup, the worker tries to acquire the opBackup task at the requested timestamp via startTaskAtTs. If the node is already running another task (e.g. an ongoing backup, export, or snapshot) at that timestamp, the operation cannot be started and the underlying error is wrapped with this message.","triggerScenarios":"Calling Backup/BackupGroup when the target node already has a conflicting task registered at opBackup with the same ReadTs — typically a concurrent backup or another long-running operation holding the task slot.","commonSituations":"Two admins trigger backups simultaneously; a previous backup hung and still holds the task; automated jobs overlap with manual backups; ReadTs collides with an in-flight operation after a retry.","solutions":["Wait for the currently running backup/task on that node to finish, then retry","Ensure only one backup is triggered at a time per group (serialize backup jobs)","Inspect the inner error from startTaskAtTs to identify the conflicting task","Restart the worker if a stale task entry is blocking new backups"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// ensure no backup task is already running for this group before issuing\nif taskRunning(opBackup) {\n    return errors.New(\"a backup operation is already in progress; wait and retry\")\n}","typeGuard":null,"tryCatchPattern":"resp, err := BackupGroup(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"cannot start backup operation\") {\n    time.Sleep(backoff)\n    resp, err = BackupGroup(ctx, req) // retry after the conflicting task completes\n}","preventionTips":["Serialize backup jobs per group with an external scheduler/lock","Alert on hung backups so stale task slots are caught early","Use exponential backoff with jitter for backup retries","Avoid overlapping manual and scheduled backups"],"tags":["concurrency","backup","task-conflict","distributed"],"backgroundTag":"operation-already-in-progress","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}