dgraph-io/dgraph · error

found a manifest with backup ID %s but expected %s

Error message

found a manifest with backup ID %s but expected %s

What it means

verifyManifests requires every manifest in the list to share the same BackupId as the newest manifest (the backupId captured from the last element). This error is thrown when a manifest from a different backup run (different BackupId) is mixed into the same directory/list, so the set of manifests does not belong to a single backup series.

Source

Thrown at worker/backup_manifest.go:39

	"github.com/dgraph-io/dgraph/v25/x"
)

func verifyManifests(manifests []*Manifest) error {
	if len(manifests) == 0 {
		return nil
	}

	lastIndex := len(manifests) - 1
	if manifests[lastIndex].BackupNum != 1 {
		return errors.Errorf("expected a BackupNum value of 1 for first manifest but got %d",
			manifests[lastIndex].BackupNum)
	}

	backupId := manifests[lastIndex].BackupId
	backupNum := uint64(len(manifests))
	for _, manifest := range manifests {
		if manifest.BackupId != backupId {
			return errors.Errorf("found a manifest with backup ID %s but expected %s",
				manifest.BackupId, backupId)
		}

		if manifest.BackupNum != backupNum {
			return errors.Errorf("found a manifest with backup number %d but expected %d",
				manifest.BackupNum, backupNum)
		}
		backupNum--
	}

	return nil
}

func getManifestsToRestore(h UriHandler, uri *url.URL, req *pb.RestoreRequest) ([]*Manifest, error) {
	manifest, err := GetManifest(h, uri)
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Separate each backup run into its own destination directory/prefix.
  2. Remove manifests not belonging to the current BackupId from the location.
  3. Re-run backup with a unique, empty destination.
  4. Check for concurrent backup jobs writing to the same path and serialize them.

Example fix

// before
dgraph backup --dst s3://bucket/shared-prefix
# second run writes different BackupId into same prefix
// after
dgraph backup --dst s3://bucket/backup-$(date +%F-%s)
Defensive patterns

Strategy: validation

Validate before calling

ids := map[string]bool{}
for _, m := range manifests {
    ids[m.BackupId] = true
}
if len(ids) > 1 {
    return fmt.Errorf("multiple BackupIds in %v; separate backup runs", ids)
}

Type guard

func singleBackupId(m []Manifest) bool {
    for i := 1; i < len(m); i++ {
        if m[i].BackupId != m[0].BackupId {
            return false
        }
    }
    return len(m) > 0
}

Prevention

When it happens

Trigger: verifyRequest detects a manifest whose BackupId differs from manifests[lastIndex].BackupId — typically two different `dgraph backup` runs written into the same location, or one backup's manifests overwritten by another run's.

Common situations: Pointing multiple backup jobs at the same S3 prefix; restoring a manifest from one backup into a directory of another; re-running backup with a fresh backupId into an existing folder.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/87073e643fc9b91f. Report an issue: GitHub.