{"record":{"id":"b915ee8f33d95c73","repo":"benbjohnson/litestream","slug":"webdav-cannot-skip-offset-in-file-q-w","errorCode":null,"errorMessage":"webdav: cannot skip offset in file %q: %w","messagePattern":"webdav: cannot skip offset in file %q: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"webdav/replica_client.go","lineNumber":337,"sourceCode":"\t\treturn internal.LimitReadCloser(rc, size), nil\n\t}\n\n\tif offset > 0 {\n\t\trc, err := client.ReadStream(filename)\n\t\tif err != nil {\n\t\t\tif os.IsNotExist(err) || gowebdav.IsErrNotFound(err) {\n\t\t\t\treturn nil, os.ErrNotExist\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"webdav: cannot read file %q: %w\", filename, err)\n\t\t}\n\n\t\tif _, err := io.CopyN(io.Discard, rc, offset); err != nil {\n\t\t\tif err == io.EOF || err == io.ErrUnexpectedEOF {\n\t\t\t\t_ = rc.Close()\n\t\t\t\treturn io.NopCloser(bytes.NewReader(nil)), nil\n\t\t\t}\n\t\t\t_ = rc.Close()\n\t\t\treturn nil, fmt.Errorf(\"webdav: cannot skip offset in file %q: %w\", filename, err)\n\t\t}\n\n\t\treturn rc, nil\n\t}\n\n\trc, err := client.ReadStream(filename)\n\tif err != nil {\n\t\tif os.IsNotExist(err) || gowebdav.IsErrNotFound(err) {\n\t\t\treturn nil, os.ErrNotExist\n\t\t}\n\t\treturn nil, fmt.Errorf(\"webdav: cannot read file %q: %w\", filename, err)\n\t}\n\treturn rc, nil\n}\n\nfunc (c *ReplicaClient) DeleteLTXFiles(ctx context.Context, a []*ltx.FileInfo) error {\n\tclient, err := c.init(ctx)\n\tif err != nil {","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/webdav/replica_client.go#L319-L355","documentation":"After opening the full stream, OpenLTXFile skips `offset` bytes using io.CopyN into io.Discard. If the stream ends before the offset is reached this is treated as an empty file (EOF handled), so this error only fires when the skip fails for another reason — a read error or write error to Discard mid-skip.","triggerScenarios":"The underlying connection errors out while discarding bytes (connection reset mid-stream, TLS truncation), i.e. reading past EOF fails hard rather than cleanly.","commonSituations":"Unstable network dropping long skip operations on big LTX files, proxies killing idle/slow responses, server prematurely closing connections.","solutions":["Retry the read; connection resets are usually transient","Check proxy idle/read timeouts and raise them for large files","Verify network stability between litestream and the WebDAV server","If the server supports ranges, prefer code paths that use ReadStreamRange"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// ensure stable connectivity for large offsets\nconn, err := net.DialTimeout(\"tcp\", host, 5*time.Second)\nif err != nil { return err }; conn.Close()","typeGuard":null,"tryCatchPattern":"rc, err := OpenLTXFile(ctx, info)\nif err != nil && strings.Contains(err.Error(), \"cannot skip offset\") {\n    // transient mid-stream failure: retry with backoff\n}","preventionTips":["Raise proxy idle/read timeouts for large files","Prefer WebDAV servers supporting Range requests","Restore over stable networks; avoid flaky VPNs"],"tags":["webdav","offset","stream"],"backgroundTag":"broken-pipe","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}