benbjohnson/litestream · error

cannot specify url & path for webdav replica

Error message

cannot specify url & path for webdav replica

What it means

newWebDAVReplicaClientFromConfig rejects configs that set both the combined 'url' and the individual 'path' field for a webdav replica. The URL should encode everything; specifying path alongside it is ambiguous and fails fast at startup.

Solutions

  1. Remove the 'path' key and keep only 'url' (put the path in the URL)
  2. Or remove 'url' and configure webdav-url/username/password/path individually
  3. Validate the final YAML contains exactly one of the two specification styles

Example fix

# before
- type: webdav
  url: webdavs://dav.example.com/db
  path: /db
# after
- type: webdav
  url: webdavs://dav.example.com/db
Defensive patterns

Strategy: validation

Validate before calling

if rep.Type == "webdav" && rep.URL != "" && rep.Path != "" {
    return fmt.Errorf("webdav replica %s: url and path are mutually exclusive", rep.Name)
}

Prevention

When it happens

Trigger: A webdav replica config where c.URL is non-empty and c.Path is also non-empty, e.g. url: 'webdavs://dav.example.com/db' plus path: /db.

Common situations: Upgrading an older per-field webdav config by adding a url without deleting the old path key; generated configs that always include 'path:'.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at cmd/litestream/main.go:1862

	client.User = user
	client.Password = password
	client.Path = path
	client.KeyPath = c.KeyPath
	client.HostKey = c.HostKey

	// Set concurrent writes if specified, otherwise use default (true)
	if c.ConcurrentWrites != nil {
		client.ConcurrentWrites = *c.ConcurrentWrites
	}

	return client, nil
}

// newWebDAVReplicaClientFromConfig returns a new instance of webdav.ReplicaClient built from config.
func newWebDAVReplicaClientFromConfig(c *ReplicaConfig, _ *litestream.Replica) (_ *webdav.ReplicaClient, err error) {
	// Ensure URL & constituent parts are not both specified.
	if c.URL != "" && c.Path != "" {
		return nil, fmt.Errorf("cannot specify url & path for webdav replica")
	} else if c.URL != "" && c.WebDAVURL != "" {
		return nil, fmt.Errorf("cannot specify url & webdav-url for webdav replica")
	}

	webdavURL, username, password, path := c.WebDAVURL, c.WebDAVUsername, c.WebDAVPassword, c.Path

	// Apply settings from URL, if specified.
	if c.URL != "" {
		u, err := url.Parse(c.URL)
		if err != nil {
			return nil, err
		}

		// Build WebDAV URL from scheme and host
		scheme := "http"
		if u.Scheme == "webdavs" {
			scheme = "https"
		}

View on GitHub (pinned to 4ed7a308f6)