benbjohnson/litestream · error
webdav: cannot connect to server: %w
Error message
webdav: cannot connect to server: %w
What it means
init performs a connectivity check via gowebdav's Connect() (a PROPFIND on the base URL) and wraps any failure with 'webdav: cannot connect to server'. The inner error carries the real cause: DNS failure, connection refused, TLS error, timeout, or an HTTP auth/status error.
Source
Thrown at webdav/replica_client.go:115
func (c *ReplicaClient) init(ctx context.Context) (_ *gowebdav.Client, err error) {
c.mu.Lock()
defer c.mu.Unlock()
if c.client != nil {
return c.client, nil
}
if c.URL == "" {
return nil, fmt.Errorf("webdav url required")
}
c.client = gowebdav.NewClient(c.URL, c.Username, c.Password)
c.client.SetTimeout(c.Timeout)
if err := c.client.Connect(); err != nil {
c.client = nil
return nil, fmt.Errorf("webdav: cannot connect to server: %w", err)
}
return c.client, nil
}
func (c *ReplicaClient) DeleteAll(ctx context.Context) error {
client, err := c.init(ctx)
if err != nil {
return err
}
if err := client.RemoveAll(c.Path); err != nil && !os.IsNotExist(err) && !gowebdav.IsErrNotFound(err) {
return fmt.Errorf("webdav: cannot delete path %q: %w", c.Path, err)
}
internal.OperationTotalCounterVec.WithLabelValues(ReplicaClientType, "DELETE").Inc()
return nilView on GitHub (pinned to 4ed7a308f6)
Solutions
- Verify reachability manually: curl -u user:pass https://host/path/ (expect 207 Multi-Status)
- Check the URL scheme and port in the replica URL — http vs https mismatches are common
- Confirm credentials; a 401 from the server surfaces wrapped inside this error
- Inspect the wrapped error (%w) for the root cause: connection refused = server/port down, x509 = TLS trust issue, timeout = network/firewall
- For self-signed TLS, add the CA to the system trust store or configure the HTTP client appropriately
Example fix
// before: opaque failure at runtime
client, err := c.Init(ctx)
// after: fail fast at startup with the underlying cause
if _, err := c.Init(context.Background()); err != nil {
log.Fatalf("webdav replica unreachable: %v", err) // inspect wrapped cause
} Defensive patterns
Strategy: retry
Validate before calling
// preflight: verify the WebDAV endpoint answers before starting replication
req, _ := http.NewRequest(http.MethodPropfind, baseURL, nil)
req.SetBasicAuth(user, pass)
resp, err := httpClient.Do(req)
if err != nil { return fmt.Errorf("webdav unreachable: %w", err) }
resp.Body.Close() Try / catch
_, err := rc.Init(ctx)
if err != nil && strings.Contains(err.Error(), "cannot connect to server") {
// retry with backoff; surface the wrapped cause
return retry.Do(func() error { _, err = rc.Init(ctx); return err }, retry.Attempts(3))
} Prevention
- Health-check the WebDAV endpoint (curl PROPFIND) before deploying config
- Match http/https scheme and port to the actual server
- Install proper TLS trust for self-signed certificates
- Verify credentials independently to rule out 401 wrapped in this error
When it happens
Trigger: Any replica operation (Init, Write, LTXFiles, DeleteAll) when the WebDAV server is unreachable, the URL/scheme/port is wrong, credentials are rejected, or TLS certificates fail validation.
Common situations: WebDAV server down or behind a NAT without port forwarding; self-signed certificate not trusted; wrong username/password (401); server URL using http where https is required (or vice versa); firewall blocking the port.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- failed to read response: %w
- http request: %w
- webdav: cannot delete path %q: %w
- webdav: cannot read directory %q: %w
- webdav: cannot write file %q: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/6055ca15adf8a8e8.
Report an issue: GitHub.