{"record":{"id":"657d95df2797e0d5","repo":"benbjohnson/litestream","slug":"unsupported-replica-url-scheme-q","errorCode":null,"errorMessage":"unsupported replica URL scheme: %q","messagePattern":"unsupported replica URL scheme: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"replica_url.go","lineNumber":49,"sourceCode":"// The URL scheme determines which backend is used (s3, gs, abs, file, etc.).\nfunc NewReplicaClientFromURL(rawURL string) (ReplicaClient, error) {\n\tscheme, host, urlPath, query, userinfo, err := ParseReplicaURLWithQuery(rawURL)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Normalize webdavs to webdav\n\tfactoryScheme := scheme\n\tif factoryScheme == \"webdavs\" {\n\t\tfactoryScheme = \"webdav\"\n\t}\n\n\treplicaClientFactoriesMu.RLock()\n\tfactory, ok := replicaClientFactories[factoryScheme]\n\treplicaClientFactoriesMu.RUnlock()\n\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unsupported replica URL scheme: %q\", scheme)\n\t}\n\n\treturn factory(scheme, host, urlPath, query, userinfo)\n}\n\n// ReplicaTypeFromURL returns the replica type from a URL string.\n// Returns empty string if the URL is invalid or has no scheme.\nfunc ReplicaTypeFromURL(rawURL string) string {\n\tif !IsURL(rawURL) {\n\t\treturn \"\"\n\t}\n\tscheme, _, _, _ := ParseReplicaURL(rawURL)\n\tif scheme == \"\" {\n\t\treturn \"\"\n\t}\n\tif scheme == \"webdavs\" {\n\t\treturn \"webdav\"\n\t}","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/replica_url.go#L31-L67","documentation":"NewReplicaClientFromURL looks up a registered ReplicaClientFactory by URL scheme; if no backend package registered a factory for that scheme (s3, gs, abs, file, sftp, webdav, ...), this error is returned. Usually it means the storage backend package was not imported, so its init() never registered the factory.","triggerScenarios":"Calling NewReplicaClientFromURL with a replica URL whose scheme has no registered factory — typically because the backend package (e.g. litestream.io/s3) isn't imported (blank import) in the binary, or the scheme string is misspelled.","commonSituations":"Building a custom binary that forgot `_ \"github.com/benbjohnson/litestream/s3\"`; using `s3a://`, `s3://` vs vendor-specific schemes, or typo'd schemes like `gcs://` instead of `gs://`; version upgrades where a backend moved packages.","solutions":["Add a blank import of the backend package so its init() registers the factory (e.g. `_ \"github.com/benbjohnson/litestream/s3\"`).","Fix the URL scheme spelling to a supported one (s3, gs, abs, file, sftp, webdav/webdavs).","If using the litestream binary, ensure it's built with the desired backends (all official builds include them).","Verify with ReplicaTypeFromURL or the registry that the scheme is registered before calling."],"exampleFix":"// before: main.go missing backend\nimport \"github.com/benbjohnson/litestream\"\nclient, err := litestream.NewReplicaClientFromURL(\"s3://bucket/db\") // unsupported scheme\n// after: blank-import the backend\nimport (\n    \"github.com/benbjohnson/litestream\"\n    _ \"github.com/benbjohnson/litestream/s3\"\n)","handlingStrategy":"validation","validationCode":"u, _ := url.Parse(replicaURL)\nsupported := map[string]bool{\"s3\": true, \"gs\": true, \"abs\": true, \"file\": true, \"sftp\": true, \"webdav\": true, \"webdavs\": true}\nif !supported[strings.ToLower(u.Scheme)] { return fmt.Errorf(\"scheme %q not compiled in; add backend import\", u.Scheme) }","typeGuard":"func schemeRegistered(rawURL string) bool {\n    u, err := url.Parse(rawURL)\n    if err != nil { return false }\n    s := strings.ToLower(u.Scheme)\n    if s == \"webdavs\" { s = \"webdav\" }\n    return litestream.ReplicaTypeFromURL(rawURL) == s && s != \"\"\n}","tryCatchPattern":"client, err := litestream.NewReplicaClientFromURL(rawURL)\nif err != nil {\n    var se *url.Error\n    if strings.Contains(err.Error(), \"unsupported replica URL scheme\") { return fmt.Errorf(\"backend for %q not linked into binary; add blank import of its package\", parseScheme(rawURL)) }\n    return err\n}","preventionTips":["Blank-import every storage backend you use in main.go.","Use official litestream release binaries which include all backends.","Validate replica URL schemes at config load time.","Use exact supported scheme spellings (gs not gcs, abs not azure)."],"tags":["config","url","replica","scheme"],"backgroundTag":"unsupported-operation","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}