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

  1. Replace `~` in the config path with the absolute home directory, e.g. `/home/litestream/data`.
  2. Ensure the process runs as a user that exists in /etc/passwd with a valid home directory.
  3. 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

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


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/42db93c00c995f4e. Report an issue: GitHub.