{"record":{"id":"165a231290f18ee9","repo":"benbjohnson/litestream","slug":"write-hydration-meta-w","errorCode":null,"errorMessage":"write hydration meta: %w","messagePattern":"write hydration meta: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"vfs.go","lineNumber":1000,"sourceCode":"\th.mu.Lock()\n\ttxid := h.txid\n\th.mu.Unlock()\n\n\tdir := filepath.Dir(h.metaPath())\n\ttmp, err := os.CreateTemp(dir, \".hydration-meta-*\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create temp meta file: %w\", err)\n\t}\n\ttmpPath := tmp.Name()\n\n\tif _, err := fmt.Fprintf(tmp, \"%d\\n\", txid); err != nil {\n\t\tif closeErr := tmp.Close(); closeErr != nil {\n\t\t\th.logger.Warn(\"failed to close temp meta file during cleanup\", \"error\", closeErr)\n\t\t}\n\t\tif removeErr := os.Remove(tmpPath); removeErr != nil {\n\t\t\th.logger.Warn(\"failed to remove temp meta file during cleanup\", \"error\", removeErr)\n\t\t}\n\t\treturn fmt.Errorf(\"write hydration meta: %w\", err)\n\t}\n\tif err := tmp.Sync(); err != nil {\n\t\tif closeErr := tmp.Close(); closeErr != nil {\n\t\t\th.logger.Warn(\"failed to close temp meta file during cleanup\", \"error\", closeErr)\n\t\t}\n\t\tif removeErr := os.Remove(tmpPath); removeErr != nil {\n\t\t\th.logger.Warn(\"failed to remove temp meta file during cleanup\", \"error\", removeErr)\n\t\t}\n\t\treturn fmt.Errorf(\"sync temp meta file: %w\", err)\n\t}\n\tif err := tmp.Close(); err != nil {\n\t\tif removeErr := os.Remove(tmpPath); removeErr != nil {\n\t\t\th.logger.Warn(\"failed to remove temp meta file during cleanup\", \"error\", removeErr)\n\t\t}\n\t\treturn fmt.Errorf(\"close temp meta file: %w\", err)\n\t}\n\tif err := os.Rename(tmpPath, h.metaPath()); err != nil {\n\t\tif removeErr := os.Remove(tmpPath); removeErr != nil {","sourceCodeStart":982,"sourceCodeEnd":1018,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/vfs.go#L982-L1018","documentation":"Hydrator.saveMeta wraps fmt.Fprintf failures writing the TXID into the temp meta file as \"write hydration meta\". On failure the temp file is closed and removed, and the error is returned; the caller (Close) logs it as a warning because losing the meta only affects resume-on-restart.","triggerScenarios":"The temp file's filesystem returns ENOSPC mid-write; the file descriptor becomes invalid (disk ejected, network filesystem dropped); write on a quota-exceeded volume.","commonSituations":"Small metadata volume that is full; NFS/network mounts with transient I/O failures; disk-hot-remove on VMs.","solutions":["Check free space on the volume holding the hydration meta (df -h, df -i)","If on NFS/network storage, check mount health and consider local disk for hydration state","This error is non-fatal for replication — the next Close with a healthy filesystem will persist the meta again"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if stat, err := os.Stat(dir); err != nil || !stat.IsDir() {\n\t// hydration directory missing — recreate before opening\n}","typeGuard":null,"tryCatchPattern":"if err := saveMeta(); err != nil {\n\tif isTransientIO(err) { time.Sleep(time.Second); err = saveMeta() }\n}","preventionTips":["Use local disks rather than NFS for hydration state","Monitor filesystem I/O errors in dmesg","Keep headroom on metadata-heavy volumes","Treat this as non-fatal: meta is a resume optimization only"],"tags":["io","filesystem","hydration"],"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-14T05:17:10.506Z"}