{"record":{"id":"633f718d973a8bc2","repo":"dgraph-io/dgraph","slug":"found-a-manifest-with-backup-number-d-but-expecte","errorCode":null,"errorMessage":"found a manifest with backup number %d but expected %d","messagePattern":"found a manifest with backup number (.+?) but expected (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"worker/backup_manifest.go","lineNumber":44,"sourceCode":"\t\treturn nil\n\t}\n\n\tlastIndex := len(manifests) - 1\n\tif manifests[lastIndex].BackupNum != 1 {\n\t\treturn errors.Errorf(\"expected a BackupNum value of 1 for first manifest but got %d\",\n\t\t\tmanifests[lastIndex].BackupNum)\n\t}\n\n\tbackupId := manifests[lastIndex].BackupId\n\tbackupNum := uint64(len(manifests))\n\tfor _, manifest := range manifests {\n\t\tif manifest.BackupId != backupId {\n\t\t\treturn errors.Errorf(\"found a manifest with backup ID %s but expected %s\",\n\t\t\t\tmanifest.BackupId, backupId)\n\t\t}\n\n\t\tif manifest.BackupNum != backupNum {\n\t\t\treturn errors.Errorf(\"found a manifest with backup number %d but expected %d\",\n\t\t\t\tmanifest.BackupNum, backupNum)\n\t\t}\n\t\tbackupNum--\n\t}\n\n\treturn nil\n}\n\nfunc getManifestsToRestore(h UriHandler, uri *url.URL, req *pb.RestoreRequest) ([]*Manifest, error) {\n\tmanifest, err := GetManifest(h, uri)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tmanifests := manifest.Manifests\n\n\t// filter takes a list of manifests and returns the list of manifests\n\t// that should be considered during a restore.\n\tfilter := func(mfs []*Manifest, backupId string) ([]*Manifest, error) {","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/worker/backup_manifest.go#L26-L62","documentation":"verifyManifests walks the manifests from newest to oldest, expecting BackupNum to decrease by exactly 1 each step down to 1. This error is thrown when a manifest's BackupNum does not equal the expected descending counter, meaning a manifest is missing, duplicated, or out of order in the backup series.","triggerScenarios":"verifyRequest walks manifests where any element's BackupNum != expected descending value — e.g. a missing manifest-N file between the full backup and the latest incremental, or duplicated/reordered files in the backup directory.","commonSituations":"Deleted single manifest file breaks the chain; manually renamed manifest files; restore directory assembled by hand; object-store listing returning duplicates.","solutions":["Restore the missing/reordered manifest file so the numbering is contiguous.","Re-copy the whole backup set from its original location.","Take a fresh full backup and use that as the restore source.","Audit the backup directory for duplicate or renamed manifest files."],"exampleFix":"// before: manifests numbered 3,2,0 (missing 1)\n// after: restore manifest file with BackupNum 1 into the backup dir\naws s3 cp s3://original/manifest-1 s3://bucket/backup/manifest-1","handlingStrategy":"validation","validationCode":"expected := len(manifests)\nfor _, m := range manifests {\n    if int(m.BackupNum) != expected {\n        return fmt.Errorf(\"chain broken: got BackupNum %d, want %d\", m.BackupNum, expected)\n    }\n    expected--\n}","typeGuard":"func isContiguousChain(m []Manifest) bool {\n    for i, v := range m {\n        if int(v.BackupNum) != len(m)-i {\n            return false\n        }\n    }\n    return true\n}","tryCatchPattern":null,"preventionTips":["Audit backup dirs for renamed/duplicate manifest files","Restore missing manifests before running restore","Take a fresh full backup if the chain cannot be repaired"],"tags":["backup","manifest","restore","sequence"],"backgroundTag":"backup-manifest-chain-incomplete","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}