benbjohnson/litestream · error
recreate L0 directory: %w
Error message
recreate L0 directory: %w
What it means
After clearing the L0 directory, checkDatabaseBehindReplica recreates it with internal.MkdirAll using the configured directory mode. This error wraps a failure to recreate the level-0 LTX directory. Without it, Litestream cannot write the fetched LTX file locally.
Source
Thrown at db.go:1620
}
// Check if database is behind replica
if dbPos.TXID >= replicaInfo.MaxTXID {
return nil // Database is ahead or equal
}
db.Logger.Info("detected database behind replica",
"db_txid", dbPos.TXID,
"replica_txid", replicaInfo.MaxTXID)
// Clear local L0 files
l0Dir := db.LTXLevelDir(0)
if err := os.RemoveAll(l0Dir); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("remove L0 directory: %w", err)
}
db.invalidatePosCache()
if err := internal.MkdirAll(l0Dir, db.dirInfo); err != nil {
return fmt.Errorf("recreate L0 directory: %w", err)
}
// Fetch latest L0 LTX file from replica
minTXID, maxTXID := replicaInfo.MinTXID, replicaInfo.MaxTXID
reader, err := db.Replica.Client.OpenLTXFile(ctx, 0, minTXID, maxTXID, 0, 0)
if err != nil {
return fmt.Errorf("open remote L0 file: %w", err)
}
defer func() { _ = reader.Close() }()
// Write to temp file and atomically rename
localPath := db.LTXPath(0, minTXID, maxTXID)
tmpPath := localPath + ".tmp"
tmpFile, err := os.Create(tmpPath)
if err != nil {
return fmt.Errorf("create temp L0 file: %w", err)
}View on GitHub (pinned to 4ed7a308f6)
Solutions
- Ensure the database's parent directory exists and is writable by the litestream user (mkdir -p, chown).
- Check disk space (df -h) and quota on the data volume.
- Check SELinux/AppAudit denial logs (ausearch -m avc) if permissions look correct.
- Compare with how litestream creates the dir at startup — if startup works but this fails, another process is interfering with the LTX directory.
Example fix
// before: directory missing at runtime // after: ensure data dir exists before starting litestream $ install -d -o litestream -g litestream /var/lib/db $ systemctl start litestream
Defensive patterns
Strategy: validation
Validate before calling
// Ensure parent dir exists and is writable before litestream starts
if err := os.MkdirAll(dbDir, 0o755); err != nil {
log.Fatalf("cannot prepare db dir: %v", err)
} Type guard
null
Try / catch
if err := internal.MkdirAll(l0Dir, db.dirInfo); err != nil {
return fmt.Errorf("recreate L0 directory: %w", err)
} // on EACCES/ENOENT, fix ownership/existence of the parent dir and retry Prevention
- Create the data directory with correct ownership before starting the service
- Do not delete the database directory while litestream is running
- Check SELinux/AppArmor policies for the litestream binary
- Monitor disk space and inode availability
When it happens
Trigger: Immediately after a successful RemoveAll of the L0 dir, internal.MkdirAll(l0Dir, db.dirInfo) fails — parent directory missing/unwritable, or the directory was recreated by another process with restrictive permissions between the two calls.
Common situations: The database directory itself was deleted or moved while litestream runs; parent dir permissions changed (mkdir-permission-denied); disk full preventing directory creation; SELinux/AppArmor blocking mkdir in the data path.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- remove L0 directory: %w
- create parent directory: %w
- create temp L0 file: %w
- close L0 file: %w
- rename L0 file: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/6e70ecc544ced129.
Report an issue: GitHub.