{"record":{"id":"8f5edb343fe14435","repo":"dgraph-io/dgraph","slug":"backup-manifest-does-not-contain-information-for-g","errorCode":null,"errorMessage":"backup manifest does not contain information for group ID %d","messagePattern":"backup manifest does not contain information for group ID (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"worker/online_restore.go","lineNumber":271,"sourceCode":"\t// filter manifests that needs to be restored\n\tmfsToRestore := manifests[:0]\n\tfor _, m := range manifests {\n\t\tif (req.BackupNum == 0 || m.BackupNum <= req.BackupNum) &&\n\t\t\t(req.IncrementalFrom == 0 || m.BackupNum >= req.IncrementalFrom) {\n\n\t\t\tmfsToRestore = append(mfsToRestore, m)\n\t\t}\n\t}\n\tmanifests = mfsToRestore\n\n\tif len(manifests) == 0 {\n\t\treturn errors.Errorf(\"no backup manifests found at location %s\", req.Location)\n\t}\n\n\tlastManifest := manifests[0]\n\trestorePreds, ok := lastManifest.Groups[req.GroupId]\n\tif !ok {\n\t\treturn errors.Errorf(\"backup manifest does not contain information for group ID %d\", req.GroupId)\n\t}\n\n\t// When we change predicate names from {fromNamespace}-predicate to 0-predicate,\n\t// this is not straight forward. This is because, Zero has a knowledge of what\n\t// predicate belongs to what group. We need to ensure that while transforming predicate names,\n\t// we let the Zero know. The algorithm that we follow here is that,\n\t// the group that had the data at the time of backup, has the data after restore.\n\t// For example, if we restore namespace 1 and 1-email belongs to group 1, after restore,\n\t// 0-email would belong to group 1 as well.\n\n\t// There are two types of predicates in a namespace:\n\n\t// 1.reserved predicates are always in group 0, we don't need to worry about those.\n\t// 2.let's understand user predicates with an example below.\n\t// Before\n\t// 0-email => group 1\n\t// 1-email => group 2\n","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/worker/online_restore.go#L253-L289","documentation":"Returned by handleRestoreProposal (worker/online_restore.go:271). The newest manifest at the location has no Groups entry for req.GroupId, so the group's Alphas have no predicate list to restore. This happens when the backup being restored predates the group or the group ID doesn't exist in the backed-up cluster.","triggerScenarios":"Restoring into a cluster whose group count/layout differs from the backup cluster (e.g. 1-group backup restored into a multi-group cluster where group 2 gets the restore request but backup has only group 1); wrong groupId in the restore request; backups taken when MaxACL/namespace reconfiguration changed group numbering.","commonSituations":"Restoring a single-group backup into a scaled-out cluster (or vice versa); ACL/user header selecting the wrong group; replica assignment changed after backup so groups were renumbered; restoring namespace-scoped (restoreTenant) requests to a group that held no data for that namespace.","solutions":["Match the restore target's group layout to the backup: restore into a cluster with the same number of groups/replicas as when the backup was taken, or take a new backup after rescaling.","Check lastManifest.Groups in the backup manifest and send the restore request with an existing groupId.","If the cluster layout must differ, restore into a cluster matching the backup first, then move tablets/scale afterwards.","Verify the correct backup set is being used (the manifest actually corresponds to the source cluster)."],"exampleFix":"// before\n{\"groupId\": 2, \"location\": \"s3://bucket/backup\"}  // manifest only has Groups: {\"1\": [...]}\n// after\n{\"groupId\": 1, \"location\": \"s3://bucket/backup\"}","handlingStrategy":"validation","validationCode":"// Inspect the backup manifest's Groups map and only request existing group IDs\ndec, _ := json.MarshalIndent(lastManifest, \"\", \"  \")\n// e.g. {\"groups\": {\"1\": [...]}} -> groupId must be 1","typeGuard":"func manifestHasGroup(manifest Manifest, groupId uint32) bool {\n    _, ok := manifest.Groups[groupId]\n    return ok\n}","tryCatchPattern":null,"preventionTips":["Restore into a cluster with the same group layout as the source cluster of the backup.","Read the backup manifest's Groups map to pick valid group IDs.","Avoid changing group counts/replica assignments between backup and restore.","Double-check the groupId field in the restore request against /state."],"tags":["dgraph","restore","group-id","cluster-layout"],"backgroundTag":"group-id-not-in-manifest","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}