dgraph-io/dgraph · error

cannot parse backup location

Error message

cannot parse backup location

What it means

Wrapped by handleRestoreProposal (worker/online_restore.go:241). The restore location string supplied in the RestoreRequest is parsed with url.Parse; this error wraps the parse failure, meaning the location is not a valid URI for a backup source (e.g. s3://, minio://, gcs://, file path).

Source

Thrown at worker/online_restore.go:241

		}
		if err := groups().Node.applyMutations(ctx, &dropProposal); err != nil {
			return err
		}
	}

	// TODO: after the drop, the tablets for the predicates stored in this group's
	// backup could be in a different group. The tablets need to be moved.

	// Reset tablets and set correct tablets to match the restored backup.
	creds := &x.MinioCredentials{
		AccessKey:    req.AccessKey,
		SecretKey:    req.SecretKey,
		SessionToken: req.SessionToken,
		Anonymous:    req.Anonymous,
	}
	uri, err := url.Parse(req.Location)
	if err != nil {
		return errors.Wrapf(err, "cannot parse backup location")
	}
	handler, err := NewUriHandler(uri, creds)
	if err != nil {
		return errors.Wrapf(err, "cannot create backup handler")
	}

	manifests, err := getManifestsToRestore(handler, uri, req)
	if err != nil {
		return errors.Wrapf(err, "cannot get backup manifests")
	}

	// filter manifests that needs to be restored
	mfsToRestore := manifests[:0]
	for _, m := range manifests {
		if (req.BackupNum == 0 || m.BackupNum <= req.BackupNum) &&
			(req.IncrementalFrom == 0 || m.BackupNum >= req.IncrementalFrom) {

			mfsToRestore = append(mfsToRestore, m)

View on GitHub (pinned to 759e242be6)

Solutions

  1. Validate the location is a well-formed URI, e.g. url.Parse it in a script before calling restore.
  2. Use the correct scheme form: s3://bucket/folder, minio://host:port/bucket, gcs://bucket/folder, or /absolute/path for filesystem backups.
  3. Percent-encode or remove spaces/special characters in bucket/folder names.
  4. Fix quoting/escaping in Helm/env config where the location value is templated.

Example fix

// before
{"location": "C:\backups\full"}
// after
{"location": "/mnt/backups/full"}
// or
{"location": "s3://my-bucket/dgraph-backups"}
Defensive patterns

Strategy: validation

Validate before calling

// Validate the backup location URI before calling restore
u, err := url.Parse(location)
if err != nil || u.Scheme == "" && !filepath.IsAbs(location) {
    return fmt.Errorf("invalid backup location: %q", location)
}

Type guard

func isValidBackupLocation(loc string) bool {
    u, err := url.Parse(loc)
    if err != nil {
        return false
    }
    switch u.Scheme {
    case "s3", "minio", "gcs", "azure", "file", "":
        return true
    }
    return false
}

Prevention

When it happens

Trigger: Calling /restore with location containing spaces or illegal characters, a bare Windows path (C:\backups), a location with an unsupported/malformed scheme, or an unescaped fragment/query.

Common situations: Copy-pasted S3 paths with trailing whitespace; storing the location in YAML/Helm values where special characters break quoting; switching from an old --restore_from style path to the URI form; Windows-style paths on Linux Alphas.

Related errors


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