benbjohnson/litestream · error
cannot expand path %s, no home directory available
Error message
cannot expand path %s, no home directory available
What it means
expandTilde (called when expanding a leading `~` in a config path) failed to determine the current user's home directory: user.Current() succeeded but returned an empty HomeDir, so there is no directory to substitute for the tilde.
Source
Thrown at cmd/litestream/main.go:2132
// expand returns an absolute path for s.
// It also strips SQLite connection string prefixes (sqlite://, sqlite3://).
func expand(s string) (string, error) {
// Strip SQLite connection string prefixes if present.
s = StripSQLitePrefix(s)
// Just expand to absolute path if there is no home directory prefix.
prefix := "~" + string(os.PathSeparator)
if s != "~" && !strings.HasPrefix(s, prefix) {
return filepath.Abs(s)
}
// Look up home directory.
u, err := user.Current()
if err != nil {
return "", err
} else if u.HomeDir == "" {
return "", fmt.Errorf("cannot expand path %s, no home directory available", s)
}
// Return path with tilde replaced by the home directory.
if s == "~" {
return u.HomeDir, nil
}
return filepath.Join(u.HomeDir, strings.TrimPrefix(s, prefix)), nil
}
// StripSQLitePrefix removes SQLite connection string prefixes (sqlite://, sqlite3://)
// from the given path. This allows users to use standard connection string formats
// across their tooling while Litestream extracts just the file path.
func StripSQLitePrefix(s string) string {
if len(s) < 9 || s[0] != 's' {
return s
}
for _, prefix := range []string{"sqlite3://", "sqlite://"} {
if strings.HasPrefix(s, prefix) {View on GitHub (pinned to 4ed7a308f6)
Solutions
- Replace `~` in the config path with the absolute home directory, e.g. `/home/litestream/data`.
- Ensure the process runs as a user that exists in /etc/passwd with a valid home directory.
- Run with HOME/userdb available in the container image, or pass an absolute path via flag/config.
Example fix
// before path: ~/data/db.sqlite // after path: /home/litestream/data/db.sqlite
Defensive patterns
Strategy: fallback
Validate before calling
// Prefer absolute paths in generated configs
u, err := user.Current()
if err != nil || u.HomeDir == "" {
return fmt.Errorf("cannot expand ~; use absolute path")
} Try / catch
if err := startLitestream(); err != nil {
if strings.Contains(err.Error(), "no home directory available") {
// rewrite config paths to absolute and retry
}
} Prevention
- Generate configs with absolute paths, never `~`.
- In containers, run as a user defined in /etc/passwd with a valid home.
- Set HOME explicitly in unit files if tilde expansion is needed.
When it happens
Trigger: A config value or flag path starts with `~` and Litestream runs in an environment where the OS user has no resolvable home directory (e.g. certain containers, service accounts, or stripped /etc/passwd entries).
Common situations: Running litestream in a scratch Docker image as a non-existent UID; systemd services with no HOME set for the user; CI runners with minimal user records.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- database not found in config: %s
- heartbeat URL must be a valid HTTP or HTTPS URL
- heartbeat interval must be at least 1 minute
- config file not found
- database config #%d: duplicate path %q (already used by data
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/42db93c00c995f4e.
Report an issue: GitHub.