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 = *v

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Move the value from `path` to the `url` field of the replica config
  2. Remove any scheme from `path`; keep only a relative directory path there if a path is needed at all
  3. 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

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


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/97ab1ea29256bfb2. Report an issue: GitHub.