dgraph-io/dgraph · error
Unable to handle url: %s
Error message
Unable to handle url: %s
What it means
NewUriHandler dispatches a backup location URI to a concrete handler based on its scheme. Only file (or empty scheme) and minio/s3 schemes are supported; any other scheme makes it return this error. It is a configuration/URI validation failure, not an I/O failure.
Source
Thrown at worker/backup_handler.go:155
// secure - true|false turn on/off TLS.
// trace - true|false turn on/off HTTP tracing.
// compress - true|false turn on/off data compression.
// encrypt - true|false turn on/off data encryption.
//
// Examples:
//
// s3://dgraph.s3.amazonaws.com/dgraph/backups?secure=true
// minio://localhost:9000/dgraph?secure=true
// file:///tmp/dgraph/backups
// /tmp/dgraph/backups?compress=gzip
func NewUriHandler(uri *url.URL, creds *x.MinioCredentials) (UriHandler, error) {
switch uri.Scheme {
case "file", "":
return NewFileHandler(uri), nil
case "minio", "s3":
return NewS3Handler(uri, creds)
}
return nil, errors.Errorf("Unable to handle url: %s", uri)
}
// fileHandler is used for 'file:' URI scheme.
type fileHandler struct {
rootDir string
prefix string
}
func NewFileHandler(uri *url.URL) *fileHandler {
h := &fileHandler{}
h.rootDir, h.prefix = filepath.Split(uri.Path)
return h
}
func (h *fileHandler) DirExists(path string) bool { return pathExist(h.JoinPath(path)) }
func (h *fileHandler) FileExists(path string) bool { return pathExist(h.JoinPath(path)) }
func (h *fileHandler) Read(path string) ([]byte, error) { return os.ReadFile(h.JoinPath(path)) }
View on GitHub (pinned to 759e242be6)
Solutions
- Check the configured backup URI scheme; use file:, minio://, or s3:// only.
- Fix typos in the scheme (e.g. gcs -> s3, files -> file).
- For GCS/Azure targets, use an S3-compatible gateway (minio) or a filesystem mount instead.
- Ensure the scheme has no stray spaces or characters in the config value.
Example fix
// before
uri, _ := url.Parse("gcs://my-bucket/backups")
h, err := NewUriHandler(uri, creds) // error
// after
uri, _ := url.Parse("s3://my-bucket/backups")
h, err := NewUriHandler(uri, creds) Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(backupURI)
if err != nil { return err }
switch u.Scheme {
case "", "file", "minio", "s3":
// ok
default:
return fmt.Errorf("unsupported backup URI scheme %q: use file:, minio:// or s3://", u.Scheme)
} Type guard
func isSupportedBackupURI(u *url.URL) bool {
return u != nil && (u.Scheme == "" || u.Scheme == "file" || u.Scheme == "minio" || u.Scheme == "s3")
} Try / catch
h, err := NewUriHandler(uri, creds)
if err != nil {
if strings.Contains(err.Error(), "Unable to handle url") {
return fmt.Errorf("backup location %q not supported; supported schemes: file, minio, s3", uri)
}
return err
} Prevention
- Validate the backup URI at config-load time, not at request time.
- Keep a shared helper that builds backup URIs to avoid scheme typos.
- Document supported schemes wherever backup locations are configured.
- Add a startup check that constructs NewUriHandler once for the configured location.
When it happens
Trigger: Calling any backup API (runExportBackup, ProcessBackupRequest, WriteBackup, CompleteBackup, ListBackupManifests, VerifyBackup) with a URI whose scheme is not file, minio, or s3 — e.g. gs://, azure://, http://, or a typo like s3s://.
Common situations: Typos in the backup location config; copying configs from other tools that use gcs:// or azure:// schemes; forgetting that empty-scheme strings are treated as local file paths; passing a full URL with https:// scheme.
Related errors
- latest manifest indicates the last backup was not encrypted
- latest manifest indicates the last backup was encrypted but
- not enough backups to restore manifest with backupNum %d
- cannot parse backup location
- connection string cannot be empty
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/7492602069d3892e.
Report an issue: GitHub.