benbjohnson/litestream · error
cannot restore, output path already exists and is not empty:
Error message
cannot restore, output path already exists and is not empty: %s. Use -force to overwrite
What it means
prepareOutputPath refuses to overwrite an existing non-empty file at the output path unless -force is given. os.Stat found a regular file whose size is greater than zero and the force flag was false, so restore aborts to avoid silently destroying existing data.
Source
Thrown at cmd/litestream/restore.go:280
if err != nil || len(infos) == 0 {
return ""
}
return infos[len(infos)-1].MaxTXID.String()
}
func (c *RestoreCommand) prepareOutputPath(path string, force bool) error {
info, err := os.Stat(path)
if os.IsNotExist(err) {
return nil
} else if err != nil {
return fmt.Errorf("cannot access output path: %w", err)
}
if info.IsDir() {
return fmt.Errorf("cannot restore, output path is a directory: %s", path)
}
if info.Size() > 0 && !force {
return fmt.Errorf("cannot restore, output path already exists and is not empty: %s. Use -force to overwrite", path)
}
for _, sidecarPath := range []string{path + "-wal", path + "-shm", path + "-journal"} {
if _, err := os.Stat(sidecarPath); err == nil && !force {
return fmt.Errorf("cannot restore, SQLite sidecar path already exists: %s. Use -force to overwrite", sidecarPath)
} else if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("cannot access SQLite sidecar path: %w", err)
}
}
for _, removePath := range []string{path, path + "-wal", path + "-shm", path + "-journal"} {
if err := os.Remove(removePath); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("remove existing output path: %w", err)
}
}
return nil
}
View on GitHub (pinned to 4ed7a308f6)
Solutions
- Re-run the restore with -force to overwrite the existing file
- Delete or move the existing file, then re-run the restore
- Choose a different -o output path
- Verify the existing file isn't needed (e.g. it's the live DB of a running app) before forcing
Example fix
// before litestream restore -o /data/app.db /path/to/db cannot restore, output path already exists and is not empty: /data/app.db. Use -force to overwrite // after litestream restore -force -o /data/app.db /path/to/db
Defensive patterns
Strategy: validation
Validate before calling
if info, err := os.Stat(outputPath); err == nil && info.Size() > 0 && !forceFlag {
return fmt.Errorf("%s exists; pass -force to overwrite", outputPath)
} Try / catch
if err := cmd.Run(ctx); err != nil {
if strings.Contains(err.Error(), "already exists and is not empty") {
// decide: add -force or pick a new output path
}
return err
} Prevention
- Clean old artifacts out of the restore target before scripted restores
- Only pass -force when you have verified the existing file is disposable
- Never restore over the live database of a running application
- In CI, use a fresh workspace or explicitly rm the target first
When it happens
Trigger: Running `litestream restore -o <path>` where <path> exists as a non-empty regular file and no -force flag is passed.
Common situations: Re-running a restore into a location that already holds a database or leftover file; a partially written file from a previous failed run; CI reusing a workspace without cleaning artifacts; restoring over the live database path of a running application.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- cannot access output path: %w
- cannot restore, output path is a directory: %s
- cannot access SQLite sidecar path: %w
- remove existing output path: %w
- rename to output path: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/f1e81c627831475a.
Report an issue: GitHub.