{"record":{"id":"0f7d5d91a04eb088","repo":"benbjohnson/litestream","slug":"write-page-d-to-hydrated-file-w","errorCode":null,"errorMessage":"write page %d to hydrated file: %w","messagePattern":"write page (.+?) to hydrated file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vfs.go","lineNumber":923,"sourceCode":"\t\t}\n\n\t\toff := int64(pgno-1) * int64(h.pageSize)\n\t\tif _, err := h.file.WriteAt(data, off); err != nil {\n\t\t\treturn fmt.Errorf(\"write updated page %d: %w\", pgno, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// WritePage writes a single page to the hydration file.\nfunc (h *Hydrator) WritePage(pgno uint32, data []byte) error {\n\th.mu.Lock()\n\tdefer h.mu.Unlock()\n\n\toff := int64(pgno-1) * int64(h.pageSize)\n\tif _, err := h.file.WriteAt(data, off); err != nil {\n\t\treturn fmt.Errorf(\"write page %d to hydrated file: %w\", pgno, err)\n\t}\n\treturn nil\n}\n\n// Truncate truncates the hydration file to the specified size.\nfunc (h *Hydrator) Truncate(size int64) error {\n\th.mu.Lock()\n\tdefer h.mu.Unlock()\n\treturn h.file.Truncate(size)\n}\n\n// Close closes the hydration file. For persistent hydrators, the file and a\n// companion .meta file are preserved so hydration can resume on the next open.\nfunc (h *Hydrator) Close() error {\n\tif h.file == nil {\n\t\treturn nil\n\t}\n","sourceCodeStart":905,"sourceCodeEnd":941,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/vfs.go#L905-L941","documentation":"Hydrator.WritePage wraps a failure writing a single page into the hydrated file as \"write page %d to hydrated file\". This is the VFS write path: SQLite hands a dirty page to litestream, which persists it into the local hydration file at (pgno-1)*pageSize.","triggerScenarios":"Disk full during a SQLite transaction commit; WriteAt issued after the hydration file was closed; underlying storage returning EIO; data slice length exceeding expectations is not the cause here — only pwrite failures.","commonSituations":"Out-of-space conditions on busy databases; nodes with read-only remounted filesystems after errors; container volume limits reached; fd closed early due to a shutdown race.","solutions":["Free disk space or enlarge the volume holding the hydration file — this is the most common cause","Inspect the wrapped error for errno (ENOSPC, EIO, EBADF) to pick the right remedy","If EBADF, check for a shutdown/close race in your embedding code that closes the VFS while writes are in flight","Use litestream reset if the hydration file is corrupted"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if fi, err := os.Stat(hydrationPath); err != nil {\n\t// hydration file missing — re-hydrate instead of writing\n}","typeGuard":null,"tryCatchPattern":"if err := hydrator.WritePage(pgno, data); err != nil {\n\tif errors.Is(err, syscall.ENOSPC) {\n\t\t// transaction will fail; free space before retrying\n\t}\n}","preventionTips":["Monitor ENOSPC early with disk usage alerts","Keep the hydration filesystem mounted read-write; alert on ro remounts","Avoid closing/shutting down the VFS while SQLite connections are active","Size volumes for the worst-case database size, not the average"],"tags":["io","filesystem","disk","vfs"],"backgroundTag":"file-write-failed","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"}