weaviate/weaviate · error
backup %q already exists at %q
Error message
backup %q already exists at %q
What it means
During backup validation the coordinator found existing backup metadata (backup_config.json) at the destination bucket/path whose status is not Cancelled — meaning a backup with that ID (or any backup occupying that slot) already exists in a valid/completed/failed-in-progress state. The scheduler refuses to overwrite; backups are identified by their destination slot, so a new backup must use a fresh ID or path.
Source
Thrown at usecases/backup/scheduler.go:867
known[r] = struct{}{}
}
for _, r := range roles {
if _, ok := known[r]; !ok {
return nil, fmt.Errorf("role %q in 'includeRoles' does not exist", r)
}
}
if len(roles) == 0 {
return nil, fmt.Errorf("no roles match 'includeRoles' %v", includeRoles)
}
return roles, nil
}
func (s *Scheduler) checkIfBackupExists(ctx context.Context, store coordStore, req *BackupRequest) error {
destPath := store.HomeDir(req.Bucket, req.Path)
// there is no backup with given id on the backend, regardless of its state (valid or corrupted)
meta, err := store.Meta(ctx, GlobalBackupFile, req.Bucket, req.Path)
if err == nil && meta.Status != backup.Cancelled {
return fmt.Errorf("backup %q already exists at %q", req.ID, destPath)
}
if !errors.As(err, &backup.ErrNotFound{}) {
return fmt.Errorf("check if backup %q exists at %q: %w", req.ID, destPath, err)
}
return nil
}
func (s *Scheduler) validateRestoreRequest(ctx context.Context, store coordStore, req *BackupRequest) (*backup.DistributedBackupDescriptor, error) {
if !store.backend.IsExternal() && s.restorer.nodeResolver.NodeCount() > 1 {
return nil, errLocalBackendDBRO
}
if len(req.Include) > 0 && len(req.Exclude) > 0 {
return nil, errIncludeExclude
}
// Check for duplicates in raw patterns early (before backend operations)
if dup := findDuplicate(req.Include); dup != "" {
return nil, fmt.Errorf("class list 'include' contains duplicate: %s", dup)View on GitHub (pinned to 75aa4b6d11)
Solutions
- Choose a new, unique backup ID (or a different path) and retry.
- If the previous backup is no longer needed, delete/cancel it first (cancel moves it to Cancelled status, which this check permits to be overwritten), then re-run.
- If the slot contains stale/corrupted metadata from an aborted operation, remove the backup slot at destPath on the backend storage, then retry.
Example fix
// before
POST /v1/backups/s3 {"id": "daily-backup"} // already exists
// after
POST /v1/backups/s3 {"id": "daily-backup-2026-09-04"} // unique ID Defensive patterns
Strategy: validation
Validate before calling
meta, err := store.Meta(ctx, "backup_config.json", bucket, path)
slotFree := err != nil || meta.Status == "CANCELLED"
if !slotFree {
return fmt.Errorf("slot %s/%s occupied; use a new backup ID", bucket, path)
} Try / catch
if err := createBackup(req); err != nil && strings.Contains(err.Error(), "already exists at") {
// cancel/delete the old backup or pick a new ID before retrying
newID := req.ID + "-" + time.Now().UTC().Format("20060102-150405")
req.ID = newID
return createBackup(req)
} Prevention
- Use time- or version-suffixed backup IDs in automation
- Cancel the prior backup before reusing its slot
- Check backup status before re-running scheduled jobs
- Never share one backup ID across concurrent pipelines
When it happens
Trigger: Calling the backup API (create) with an ID whose destination (bucket+path) already holds metadata from a previous backup that succeeded, is running, or failed but wasn't cancelled. Also hit when re-running a backup job that already completed.
Common situations: Re-running a scheduled backup script with the same backup ID without cleanup; retrying after a failed run that left recoverable metadata; two pipelines racing with the same ID; restoring from an old config that still references a used ID.
Related errors
- export already exists
- %w: shard %q (collection %q) has an active runtime-reindex t
- pause compaction: %w
- list backup files: %w
- close writer for gcs write %q: %w
AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04).
Data as JSON: /api/errors/447ccd2dd5530679.
Report an issue: GitHub.