{"record":{"id":"900c08b295c29885","repo":"benbjohnson/litestream","slug":"remove-stale-hydration-meta-w","errorCode":null,"errorMessage":"remove stale hydration meta: %w","messagePattern":"remove stale hydration meta: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vfs.go","lineNumber":697,"sourceCode":"func (h *Hydrator) Init() error {\n\tif err := os.MkdirAll(filepath.Dir(h.path), 0755); err != nil {\n\t\treturn fmt.Errorf(\"create hydration directory: %w\", err)\n\t}\n\n\tif h.persistent {\n\t\tif txid, err := h.loadMeta(); err == nil {\n\t\t\tif _, statErr := os.Stat(h.path); statErr == nil {\n\t\t\t\tfile, err := os.OpenFile(h.path, os.O_RDWR, 0600)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"open persistent hydration file: %w\", err)\n\t\t\t\t}\n\t\t\t\th.file = file\n\t\t\t\th.txid = txid\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tif err := os.Remove(h.metaPath()); err != nil && !os.IsNotExist(err) {\n\t\t\treturn fmt.Errorf(\"remove stale hydration meta: %w\", err)\n\t\t}\n\t}\n\n\tfile, err := os.OpenFile(h.path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create hydration file: %w\", err)\n\t}\n\th.file = file\n\treturn nil\n}\n\n// Complete returns true if hydration has completed.\nfunc (h *Hydrator) Complete() bool {\n\treturn h.complete.Load()\n}\n\n// SetComplete marks hydration as complete.\nfunc (h *Hydrator) SetComplete() {","sourceCodeStart":679,"sourceCodeEnd":715,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/vfs.go#L679-L715","documentation":"For a persistent hydrator whose metadata is stale or whose hydration file is missing, Init removes the leftover meta file before recreating the hydration file. This error wraps os.Remove failing on the meta file (any error other than NotExist). It indicates stale hydration state could not be cleaned up, so Init aborts rather than continue with inconsistent on-disk state.","triggerScenarios":"Persistent hydration Init where loadMeta fails or the hydration file is absent, and deleting the meta file fails due to directory permissions, immutable flag, or I/O error on the containing directory.","commonSituations":"Directory owned by a different user after a container image update; chattr +i applied by hardening scripts; read-only remount of the volume mid-run.","solutions":["Grant the process user write+execute permission on the hydration directory so it can unlink files.","Remove the immutable attribute if set (chattr -i <meta-file>) or check for read-only mounts (mount | grep ro).","Manually delete the stale meta file as an administrator and retry Init.","Nuke the whole hydration directory and let Init rebuild it if state is disposable."],"exampleFix":"// before\n$ lsattr hydration.db.meta\n----i--------- hydration.db.meta  # immutable\n\n// after\n$ sudo chattr -i hydration.db.meta && rm hydration.db.meta  # then retry Init","handlingStrategy":"try-catch","validationCode":"mp := hydrator.MetaPath()\ndir := filepath.Dir(mp)\nif err := unix.Access(dir, unix.W_OK); err != nil {\n    return fmt.Errorf(\"cannot unlink in %q: %w\", dir, err)\n}","typeGuard":null,"tryCatchPattern":"if err := hydrator.Init(); err != nil && strings.Contains(err.Error(), \"remove stale hydration meta\") {\n    // check dir perms / immutable flags / ro mount, clean manually, retry\n}","preventionTips":["Keep hydration directory writable (no chattr +i, no hardening scripts adding immutable bits).","Avoid read-only remounts on the volume during operation.","Deploy-time provisioning should match the runtime user.","Treat hydration dir contents as disposable cleanup candidates in runbooks."],"tags":["go","filesystem","hydration","cleanup"],"backgroundTag":"permission-denied","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"}