{"record":{"id":"6055ca15adf8a8e8","repo":"benbjohnson/litestream","slug":"webdav-cannot-connect-to-server-w","errorCode":null,"errorMessage":"webdav: cannot connect to server: %w","messagePattern":"webdav: cannot connect to server: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"webdav/replica_client.go","lineNumber":115,"sourceCode":"func (c *ReplicaClient) init(ctx context.Context) (_ *gowebdav.Client, err error) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\tif c.client != nil {\n\t\treturn c.client, nil\n\t}\n\n\tif c.URL == \"\" {\n\t\treturn nil, fmt.Errorf(\"webdav url required\")\n\t}\n\n\tc.client = gowebdav.NewClient(c.URL, c.Username, c.Password)\n\n\tc.client.SetTimeout(c.Timeout)\n\n\tif err := c.client.Connect(); err != nil {\n\t\tc.client = nil\n\t\treturn nil, fmt.Errorf(\"webdav: cannot connect to server: %w\", err)\n\t}\n\n\treturn c.client, nil\n}\n\nfunc (c *ReplicaClient) DeleteAll(ctx context.Context) error {\n\tclient, err := c.init(ctx)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := client.RemoveAll(c.Path); err != nil && !os.IsNotExist(err) && !gowebdav.IsErrNotFound(err) {\n\t\treturn fmt.Errorf(\"webdav: cannot delete path %q: %w\", c.Path, err)\n\t}\n\n\tinternal.OperationTotalCounterVec.WithLabelValues(ReplicaClientType, \"DELETE\").Inc()\n\n\treturn nil","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/webdav/replica_client.go#L97-L133","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: opaque failure at runtime\nclient, err := c.Init(ctx)\n// after: fail fast at startup with the underlying cause\nif _, err := c.Init(context.Background()); err != nil {\n    log.Fatalf(\"webdav replica unreachable: %v\", err) // inspect wrapped cause\n}","handlingStrategy":"retry","validationCode":"// preflight: verify the WebDAV endpoint answers before starting replication\nreq, _ := http.NewRequest(http.MethodPropfind, baseURL, nil)\nreq.SetBasicAuth(user, pass)\nresp, err := httpClient.Do(req)\nif err != nil { return fmt.Errorf(\"webdav unreachable: %w\", err) }\nresp.Body.Close()","typeGuard":null,"tryCatchPattern":"_, err := rc.Init(ctx)\nif err != nil && strings.Contains(err.Error(), \"cannot connect to server\") {\n    // retry with backoff; surface the wrapped cause\n    return retry.Do(func() error { _, err = rc.Init(ctx); return err }, retry.Attempts(3))\n}","preventionTips":["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"],"tags":["webdav","network","connectivity","http"],"backgroundTag":"connection-refused","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}