benbjohnson/litestream · error
replica path cannot be a url, please use the 'url' field ins
Error message
replica path cannot be a url, please use the 'url' field instead: %s
What it means
NewReplicaFromConfig rejects a replica config whose `path` field looks like a URL (litestream.IsURL). In modern Litestream, replica destinations are specified with `url`; a path containing "://" (or another URL-like form) indicates a stale config style and would be misinterpreted.
Source
Thrown at cmd/litestream/main.go:1353
rs.Age.Recipients = src.Age.Recipients
}
}
// ReplicaConfig represents the configuration for a single replica in a database.
type ReplicaConfig struct {
ReplicaSettings `yaml:",inline"`
Type string `yaml:"type"` // "file", "s3"
Name string `yaml:"name"` // Deprecated
Path string `yaml:"path"`
URL string `yaml:"url"`
}
// NewReplicaFromConfig instantiates a replica for a DB based on a config.
func NewReplicaFromConfig(c *ReplicaConfig, db *litestream.DB) (_ *litestream.Replica, err error) {
// Ensure user did not specify URL in path.
if litestream.IsURL(c.Path) {
return nil, fmt.Errorf("replica path cannot be a url, please use the 'url' field instead: %s", c.Path)
}
// Reject age encryption configuration as it's currently non-functional.
// Age encryption support was removed during the LTX storage layer refactor
// and has not been reimplemented. Accepting this config would silently
// write plaintext data to remote storage instead of encrypted data.
// See: https://github.com/benbjohnson/litestream/issues/790
if len(c.Age.Identities) > 0 || len(c.Age.Recipients) > 0 {
return nil, fmt.Errorf("age encryption is not currently supported, if you need encryption please revert back to Litestream v0.3.x")
}
// Build replica.
r := litestream.NewReplica(db)
if v := c.SyncInterval; v != nil {
r.SyncInterval = *v
}
if v := c.MaxSyncLTXFiles; v != nil {
r.MaxSyncLTXFiles = *vView on GitHub (pinned to 4ed7a308f6)
Solutions
- Move the value from `path` to the `url` field of the replica config
- Remove any scheme from `path`; keep only a relative directory path there if a path is needed at all
- Run `litestream replicate -config <file>` again after fixing; this check fires at replica construction time
Example fix
# before replicas: - path: s3://mybucket/db # after replicas: - url: s3://mybucket/db
Defensive patterns
Strategy: validation
Validate before calling
for _, r := range cfg.Replicas {
if litestream.IsURL(r.Path) {
return fmt.Errorf("replica %q: move path %q to the url field", r.Name, r.Path)
}
} Type guard
func isURL(s string) bool { return strings.Contains(s, "://") } Prevention
- Always use `url` for replica destinations; reserve `path` for relative dirs
- When migrating from v0.3.x, rewrite path-URLs to url fields
- Grep configs for `path:.*://` in CI
When it happens
Trigger: Config contains `replicas: [{path: s3://bucket/db}]` or a top-level replica `path` starting with a scheme like `s3://`, `file://`, `gs://` — checked when the replica is instantiated at startup.
Common situations: Upgrading from v0.3.x where path-URLs were accepted; copying an example config that put the URL under `path`; mixing `path` and `url` conventions.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- multiple replicas on a single database are no longer support
- failed to configure replica for %s: %w
- unsupported replica URL scheme: %q
- heartbeat URL must be a valid HTTP or HTTPS URL
- must specify replica for database
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/97ab1ea29256bfb2.
Report an issue: GitHub.