{"record":{"id":"5e15e386dfe316af","repo":"benbjohnson/litestream","slug":"replica-url-scheme-required-s","errorCode":null,"errorMessage":"replica url scheme required: %s","messagePattern":"replica url scheme required: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"replica_url.go","lineNumber":103,"sourceCode":"\tif strings.HasPrefix(strings.ToLower(s), \"s3://arn:\") {\n\t\tscheme, host, urlPath, query, err := parseS3AccessPointURL(s)\n\t\treturn scheme, host, urlPath, query, nil, err\n\t}\n\n\tu, err := url.Parse(s)\n\tif err != nil {\n\t\treturn \"\", \"\", \"\", nil, nil, err\n\t}\n\n\tswitch u.Scheme {\n\tcase \"file\":\n\t\tscheme, u.Scheme = u.Scheme, \"\"\n\t\t// Remove query params from path for file URLs\n\t\tu.RawQuery = \"\"\n\t\treturn scheme, \"\", path.Clean(u.String()), nil, nil, nil\n\n\tcase \"\":\n\t\treturn u.Scheme, u.Host, u.Path, nil, nil, fmt.Errorf(\"replica url scheme required: %s\", s)\n\n\tdefault:\n\t\treturn u.Scheme, u.Host, strings.TrimPrefix(path.Clean(u.Path), \"/\"), u.Query(), u.User, nil\n\t}\n}\n\n// parseS3AccessPointURL parses an S3 Access Point URL (s3://arn:...).\nfunc parseS3AccessPointURL(s string) (scheme, host, urlPath string, query url.Values, err error) {\n\tconst prefix = \"s3://\"\n\tif !strings.HasPrefix(strings.ToLower(s), prefix) {\n\t\treturn \"\", \"\", \"\", nil, fmt.Errorf(\"invalid s3 access point url: %s\", s)\n\t}\n\n\tarnWithPath := s[len(prefix):]\n\n\t// Split off query string if present\n\tvar queryStr string\n\tif idx := strings.IndexByte(arnWithPath, '?'); idx != -1 {","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/replica_url.go#L85-L121","documentation":"ParseReplicaURLWithQuery requires every replica URL to carry a scheme; when url.Parse yields an empty scheme (bare path like \"/path/to/replica\" or \"localhost:9000/bucket\"), this error is returned. The library cannot pick a storage backend without a scheme.","triggerScenarios":"Passing a replica URL string with no scheme to ParseReplicaURL/NewReplicaClientFromURL — e.g. a filesystem path without the file:// prefix, or a host/bucket string with no s3:// prefix.","commonSituations":"YAML config with `url: /mnt/backup/db` instead of `file:///mnt/backup/db`; passing `mybucket/db` instead of `s3://mybucket/db`; env-substitution producing an empty scheme (`$REPLICA_TYPE://...` with REPLICAS_TYPE unset is a different case, but a URL of only a path hits this).","solutions":["Prefix the path with file:// for local replicas (file:///mnt/backup/db).","Add the correct storage scheme to the URL (s3://, gs://, abs://, sftp://, webdav://).","Validate the replica URL in config before starting litestream (scheme non-empty).","Check env-var expansion in the config file didn't drop the scheme prefix."],"exampleFix":"// before: config with bare path\nreplica: { url: \"/mnt/backup/db\" } // replica url scheme required\n// after\nreplica: { url: \"file:///mnt/backup/db\" }","handlingStrategy":"validation","validationCode":"u, err := url.Parse(replicaURL)\nif err != nil { return err }\nif u.Scheme == \"\" { return fmt.Errorf(\"replica URL %q needs a scheme (file://, s3://, gs://, ...)\", replicaURL) }","typeGuard":"func hasReplicaScheme(rawURL string) bool {\n    u, err := url.Parse(rawURL)\n    return err == nil && u.Scheme != \"\"\n}","tryCatchPattern":"if _, err := litestream.ParseReplicaURL(cfg.ReplicaURL); err != nil {\n    return fmt.Errorf(\"invalid replica URL in config: %w\", err)\n}","preventionTips":["Always use absolute replica URLs with explicit scheme in litestream.yml.","Prefix local paths with file:// (file:///mnt/backup/db).","Check env-var expansion in configs didn't swallow the scheme prefix.","Fail fast on config validation before starting the Store."],"tags":["config","url","validation"],"backgroundTag":"invalid-url-format","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}