benbjohnson/litestream · error
create temp dir for write buffer: %w
Error message
create temp dir for write buffer: %w
What it means
In openMainDB, when no explicit bufferPath is configured, Litestream calls vfs.ensureTempDir() to obtain (or create) a temporary directory used to buffer writes before they are staged for upload. This error wraps any failure of that directory creation. Litestream throws it because the write buffer requires local disk space and a writable directory to operate.
Source
Thrown at vfs.go:236
if writeEnabled {
f.writeEnabled = true
f.dirty = make(map[uint32]int64)
f.syncInterval = syncInterval
if f.syncInterval == 0 {
f.syncInterval = DefaultSyncInterval
}
writeSeq := atomic.AddUint64(&vfs.writeSeq, 1)
if bufferPath != "" {
if writeSeq == 1 {
f.bufferPath = bufferPath
} else {
f.bufferPath = bufferPath + "." + strconv.FormatUint(writeSeq, 10)
}
} else {
dir, err := vfs.ensureTempDir()
if err != nil {
return nil, 0, fmt.Errorf("create temp dir for write buffer: %w", err)
}
f.bufferPath = filepath.Join(dir, "write-buffer-"+strconv.FormatUint(writeSeq, 10))
}
// Initialize compaction if enabled
if vfs.CompactionEnabled {
f.compactor = NewCompactor(client, f.logger)
}
}
// Initialize hydration support if enabled
if hydrationEnabled {
if hydrationPath != "" {
f.hydrationPath = hydrationPath
f.hydrationPersistent = true
} else {
dir, err := vfs.ensureTempDir()
if err != nil {View on GitHub (pinned to 4ed7a308f6)
Solutions
- Point TMPDIR (or os.TempDir's source) at a writable directory before opening the connection.
- Configure an explicit buffer path in the VFS config so Litestream skips the temp-dir lookup and uses your own writable location.
- Mount a writable tmpfs/emptyDir volume at /tmp in containers and ensure the process user owns it.
- Check disk space and permissions (ls -ld $TMPDIR; df -h) on the target filesystem.
Example fix
// before
// TMPDIR=/nonexistent, container fs read-only
db, err := sql.Open("sqlite", "file:app.db?vfs=litestream&replica_url=s3://bucket/app.db")
// after
os.Setenv("TMPDIR", "/var/tmp/app") // writable volume
db, err := sql.Open("sqlite", "file:app.db?vfs=litestream&replica_url=s3://bucket/app.db") Defensive patterns
Strategy: validation
Validate before calling
tmp := os.TempDir()
if fi, err := os.Stat(tmp); err != nil || !fi.IsDir() {
return fmt.Errorf("temp dir %q unusable: %w", tmp, err)
}
probe, err := os.CreateTemp(tmp, "litestream-probe-*")
if err != nil { return err }
probe.Remove() Try / catch
db, err := sql.Open("sqlite", dsn)
if err != nil && strings.Contains(err.Error(), "create temp dir for write buffer") {
os.Setenv("TMPDIR", "/var/tmp/app")
return reopenDB(dsn)
} Prevention
- Ensure TMPDIR points to an existing, writable directory in every deployment
- Mount a writable tmpfs/emptyDir at /tmp in containers with read-only root filesystems
- Configure an explicit buffer path in VFSConfig to bypass temp-dir resolution
- Monitor free disk space on the temp filesystem; writes fail when it is full
When it happens
Trigger: Opening a VFS database when the temp directory cannot be created or found: os.TempDir() points to a non-writable path, TMPDIR is set to a nonexistent or permission-denied directory, or the filesystem holding /tmp is full/read-only.
Common situations: Containers with read-only root filesystems and no tmpfs mounted at /tmp; serverless environments with restricted /tmp; running as a non-root user with TMPDIR pointing at another user's directory; disk-full conditions on small instances.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- cannot access output path: %w
- cannot access SQLite sidecar path: %w
- remove existing output path: %w
- remove ltx directory: %w
- stat database: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/bddd26f0572b060f.
Report an issue: GitHub.