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

  1. Check the configured backup URI scheme; use file:, minio://, or s3:// only.
  2. Fix typos in the scheme (e.g. gcs -> s3, files -> file).
  3. For GCS/Azure targets, use an S3-compatible gateway (minio) or a filesystem mount instead.
  4. 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

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


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