benbjohnson/litestream · error
database config #%d: cannot specify both 'meta-path' and 'me
Error message
database config #%d: cannot specify both 'meta-path' and 'meta-dir'
What it means
Validate() rejects a database config entry specifying both 'meta-path' and 'meta-dir'. These are mutually exclusive ways to locate metadata: meta-path for a single database file, meta-dir for directory replication. Only one may be set.
Source
Thrown at cmd/litestream/main.go:524
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,
}
}
if db.Snapshot.Retention != nil && *db.Snapshot.Retention <= 0 {
return &ConfigValidationError{
Err: ErrInvalidSnapshotRetention,View on GitHub (pinned to 4ed7a308f6)
Solutions
- Keep only meta-path if the entry targets a single database via `path:`.
- Keep only meta-dir if the entry targets a directory via `dir:`.
- Delete both to use default metadata locations.
Example fix
# before
databases:
- dir: /var/db
pattern: "*.db"
meta-path: /tmp/meta
meta-dir: /var/lib/meta
# after
databases:
- dir: /var/db
pattern: "*.db"
meta-dir: /var/lib/meta Defensive patterns
Strategy: validation
Validate before calling
if db.MetaPath != nil && db.MetaDir != nil {
return fmt.Errorf("db #%d: set only one of meta-path/meta-dir", i+1)
} Prevention
- Never copy meta keys across dir/path entry types
- Run a config linter that flags mutually exclusive keys
- Keep one canonical config template per entry type
When it happens
Trigger: A databases[] entry in the config contains both `meta-path:` and `meta-dir:` keys; Validate runs during ParseConfig and fails with this message including the 1-based database index.
Common situations: User merges a single-DB config snippet (meta-path) with a directory snippet (meta-dir) into one entry; leftover key from a config refactor.
Related errors
- database config #%d: 'watch' can only be enabled with a dire
- database config #%d: 'meta-dir' can only be used with a dire
- 'meta-dir' can only be used with a directory
- directory path is required for directory replication
- pattern is required for directory replication
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/35adff6358e1bbf7.
Report an issue: GitHub.