benbjohnson/litestream · error
invalid scheme for NATS replica: %s
Error message
invalid scheme for NATS replica: %s
What it means
After successfully parsing c.URL, newNATSReplicaClientFromConfig verifies the scheme equals 'nats'. Any other scheme (s3, abs, file, sftp, ...) means the URL describes a different backend, so this error reports the offending scheme verbatim.
Source
Thrown at cmd/litestream/main.go:1922
client.URL = webdavURL
client.Username = username
client.Password = password
client.Path = path
return client, nil
}
// newNATSReplicaClientFromConfig returns a new instance of nats.ReplicaClient built from config.
func newNATSReplicaClientFromConfig(c *ReplicaConfig, _ *litestream.Replica) (_ *nats.ReplicaClient, err error) {
// Parse URL if provided to extract bucket name and server URL
var url, bucket string
if c.URL != "" {
scheme, host, bucketPath, err := litestream.ParseReplicaURL(c.URL)
if err != nil {
return nil, fmt.Errorf("invalid NATS URL: %w", err)
}
if scheme != "nats" {
return nil, fmt.Errorf("invalid scheme for NATS replica: %s", scheme)
}
// Reconstruct URL without bucket path
if host != "" {
url = fmt.Sprintf("nats://%s", host)
}
// Extract bucket name from path
if bucketPath != "" {
bucket = strings.Trim(bucketPath, "/")
}
}
// Use bucket from config if not extracted from URL
if bucket == "" {
bucket = c.Bucket
}
View on GitHub (pinned to 4ed7a308f6)
Solutions
- Change the URL scheme to 'nats://', e.g. 'nats://nats.example.com:4222/mybucket'
- Or change the replica type to match the scheme you actually intended
- Search the config for other replica blocks and ensure url schemes align with each block's type
Example fix
# before - type: nats url: s3://mybucket/db # after - type: nats url: nats://nats.example.com:4222/mybucket
Defensive patterns
Strategy: validation
Validate before calling
if rep.Type == "nats" && rep.URL != "" {
if scheme, _, _, err := litestream.ParseReplicaURL(rep.URL); err == nil && scheme != "nats" {
return fmt.Errorf("nats replica %s: expected nats:// scheme, got %s", rep.Name, scheme)
}
} Type guard
func isNATSScheme(raw string) bool {
scheme, _, _, err := litestream.ParseReplicaURL(raw)
return err == nil && scheme == "nats"
} Prevention
- Keep replica type and url scheme consistent per block
- Never copy urls between replica blocks of different types
- Grep configs for url schemes that don't match their block type
When it happens
Trigger: A nats replica whose 'url' uses a non-nats scheme, e.g. url: 's3://bucket/path' inside a type: nats block, or a typo like 'nats2://host/bucket'.
Common situations: Copy-pasting a replica URL from another backend's config into a nats replica block; swapping replica 'type' without updating the url scheme.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- invalid NATS URL: %w
- failed to configure replica for %s: %w
- bucket required for nats replica URL
- heartbeat URL must be a valid HTTP or HTTPS URL
- database config #%d: 'watch' can only be enabled with a dire
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/e02197df03e3d313.
Report an issue: GitHub.