benbjohnson/litestream · error

database config #%d: 'meta-dir' can only be used with a dire

Error message

database config #%d: 'meta-dir' can only be used with a directory

What it means

Validate() rejects a database config entry that sets 'meta-dir' without a 'dir'. The meta-dir option (where Litestream stores metadata for directory-managed databases) only applies to directory replication, so it is invalid on a single-path database entry.

Source

Thrown at cmd/litestream/main.go:521

		// derived from the path, so two entries would share it and race on the
		// same LTX temp files.
		if db.Path != "" {
			key := filepath.Clean(db.Path)
			if first, ok := seenPaths[key]; ok {
				return fmt.Errorf("database config #%d: duplicate path %q (already used by database config #%d); each database can be listed only once", idx+1, db.Path, first)
			}
			seenPaths[key] = idx + 1
		}

		// When using dir, pattern must be specified
		if db.Dir != "" && db.Pattern == "" {
			return fmt.Errorf("database config #%d: 'pattern' is required when using 'dir'", idx+1)
		}
		if db.Watch && db.Dir == "" {
			return fmt.Errorf("database config #%d: 'watch' can only be enabled with a directory", idx+1)
		}
		if db.MetaDir != nil && db.Dir == "" {
			return fmt.Errorf("database config #%d: 'meta-dir' can only be used with a directory", idx+1)
		}
		if db.MetaPath != nil && db.MetaDir != nil {
			return fmt.Errorf("database config #%d: cannot specify both 'meta-path' and 'meta-dir'", idx+1)
		}

		// Use path or dir for identifying the config in error messages
		dbIdentifier := db.Path
		if dbIdentifier == "" {
			dbIdentifier = db.Dir
		}

		if db.Snapshot.Interval != nil && *db.Snapshot.Interval <= 0 {
			return &ConfigValidationError{
				Err:   ErrInvalidSnapshotInterval,
				Field: fmt.Sprintf("dbs[%s].snapshot.interval", dbIdentifier),
				Value: *db.Snapshot.Interval,
			}
		}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. For a single-database entry, replace `meta-dir:` with `meta-path:` to set a custom metadata location.
  2. Or switch the entry to directory replication by adding `dir:` (plus `pattern:`), which permits meta-dir.
  3. Or remove meta-dir entirely if default metadata placement is fine.

Example fix

# before
databases:
  - path: /var/db/app.db
    meta-dir: /var/lib/litestream-meta
# after
databases:
  - path: /var/db/app.db
    meta-path: /var/lib/litestream-meta/app
Defensive patterns

Strategy: validation

Validate before calling

if db.MetaDir != nil && db.Dir == "" {
    return fmt.Errorf("db #%d: 'meta-dir' requires 'dir'", i+1)
}

Prevention

When it happens

Trigger: Running `litestream` with a databases[] entry containing `meta-dir:` while `dir:` is absent (only `path:` or nothing). Caught by Validate during ParseConfig.

Common situations: User adds meta-dir to a single-database config intending to relocate metadata; user confuses meta-dir with meta-path, which is the valid option for single-DB configs.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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