{"record":{"id":"9735bb499ae2fe09","repo":"benbjohnson/litestream","slug":"create-temp-dir-for-hydration-w","errorCode":null,"errorMessage":"create temp dir for hydration: %w","messagePattern":"create temp dir for hydration: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vfs.go","lineNumber":255,"sourceCode":"\t\t\t}\n\t\t\tf.bufferPath = filepath.Join(dir, \"write-buffer-\"+strconv.FormatUint(writeSeq, 10))\n\t\t}\n\n\t\t// Initialize compaction if enabled\n\t\tif vfs.CompactionEnabled {\n\t\t\tf.compactor = NewCompactor(client, f.logger)\n\t\t}\n\t}\n\n\t// Initialize hydration support if enabled\n\tif hydrationEnabled {\n\t\tif hydrationPath != \"\" {\n\t\t\tf.hydrationPath = hydrationPath\n\t\t\tf.hydrationPersistent = true\n\t\t} else {\n\t\t\tdir, err := vfs.ensureTempDir()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, 0, fmt.Errorf(\"create temp dir for hydration: %w\", err)\n\t\t\t}\n\t\t\tf.hydrationPath = filepath.Join(dir, \"hydration.db\")\n\t\t}\n\t}\n\n\tif err := f.Open(); err != nil {\n\t\tif perConnClient {\n\t\t\tif closer, ok := client.(io.Closer); ok {\n\t\t\t\tcloser.Close()\n\t\t\t}\n\t\t}\n\t\treturn nil, 0, err\n\t}\n\n\tif writeEnabled {\n\t\tvfs.writeMu.Lock()\n\t\tif f.expectedTXID > vfs.lastSyncedTXID {\n\t\t\tvfs.lastSyncedTXID = f.expectedTXID","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/vfs.go#L237-L273","documentation":"During xOpen of the Litestream VFS, when hydration is enabled and no explicit hydration path was configured, the VFS must create a temporary OS directory (via os.MkdirTemp) to hold the hydration database file. This error wraps the failure of that directory creation. It is thrown by openMainDB because the VFS cannot prepare local scratch space needed before the main database file can be opened.","triggerScenarios":"Opening a database through the litestream VFS (sqlite3vfs Open on the registered VFS name) with hydration enabled, no hydrationPath configured, and os.MkdirTemp(\"\") failing — typically because TMPDIR points to a nonexistent/unwritable location or the filesystem is full.","commonSituations":"Containers run with TMPDIR set to a read-only or deleted directory; disk-full on the temp volume; restricted sandbox (e.g. hardened CI runners) that denies temp directory creation; misconfigured systemd PrivateTmp or seccomp filters blocking mkdir in /tmp.","solutions":["Check that TMPDIR points to an existing, writable directory and that the volume has free space (df -h $TMPDIR).","Configure an explicit hydration path via the VFS config/URI parameter so the fallback temp dir is never used.","Verify the process user can create directories in the temp location (test with: touch $TMPDIR/probe).","If running in a container, mount a writable tmpfs at /tmp or the configured TMPDIR."],"exampleFix":"// before (failing because TMPDIR is unwritable)\nos.Setenv(\"TMPDIR\", \"/readonly\")\nsql.Open(\"sqlite3\", \"file:app.db?vfs=litestream\")\n\n// after\ndir, _ := os.MkdirTemp(\"\", \"litestream-check\") // or ensure /tmp is writable\nos.Setenv(\"TMPDIR\", dir)\nsql.Open(\"sqlite3\", \"file:app.db?vfs=litestream\")","handlingStrategy":"validation","validationCode":"dir := os.TempDir()\nif fi, err := os.Stat(dir); err != nil || !fi.IsDir() {\n    return fmt.Errorf(\"temp dir %q unusable: %w\", dir, err)\n}\nprobe, err := os.CreateTemp(dir, \"litestream-probe-*\")\nif err != nil { return err }\nprobe.Close(); os.Remove(probe.Name())","typeGuard":null,"tryCatchPattern":"f, _, err := vfs.Open(name, flags)\nif err != nil && strings.Contains(err.Error(), \"create temp dir for hydration\") {\n    // fix TMPDIR or set explicit hydrationPath, then retry\n}","preventionTips":["Prefer configuring an explicit hydrationPath over relying on the shared temp dir.","Health-check TMPDIR writability at process startup.","Mount a writable tmpfs for /tmp in containers.","Monitor temp volume free space."],"tags":["go","filesystem","temp-directory","vfs"],"backgroundTag":"mkdir-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"}