juanfont/headscale · error · ErrInvalidJournalMode
%w: %s
Error message
%w: %s
What it means
Config.Validate rejected the configured SQLite journal_mode: the value is non-empty but not one of the valid JournalMode pragma values (WAL, DELETE, TRUNCATE, PERSIST, MEMORY, OFF). The sentinel ErrInvalidJournalMode is wrapped with the bad value. Journal mode controls write concurrency and crash recovery behavior.
Source
Thrown at hscontrol/db/sqliteconfig/config.go:322
return &Config{
Path: ":memory:",
WALAutocheckpoint: -1, // not set, use driver default
ForeignKeys: true,
}
}
// Validate checks if all configuration values are valid.
func (c *Config) Validate() error {
if c.Path == "" {
return ErrPathEmpty
}
if c.BusyTimeout < 0 {
return fmt.Errorf("%w, got %d", ErrBusyTimeoutNegative, c.BusyTimeout)
}
if c.JournalMode != "" && !c.JournalMode.IsValid() {
return fmt.Errorf("%w: %s", ErrInvalidJournalMode, c.JournalMode)
}
if c.AutoVacuum != "" && !c.AutoVacuum.IsValid() {
return fmt.Errorf("%w: %s", ErrInvalidAutoVacuum, c.AutoVacuum)
}
if c.WALAutocheckpoint < -1 {
return fmt.Errorf("%w, got %d", ErrWALAutocheckpoint, c.WALAutocheckpoint)
}
if c.Synchronous != "" && !c.Synchronous.IsValid() {
return fmt.Errorf("%w: %s", ErrInvalidSynchronous, c.Synchronous)
}
if c.TxLock != "" && !c.TxLock.IsValid() {
return fmt.Errorf("%w: %s", ErrInvalidTxLock, c.TxLock)
}
View on GitHub (pinned to 565fd254d0)
Solutions
- Use one of the exported constants: sqliteconfig.JournalModeWAL (recommended for production), JournalModeDelete, etc.
- If loading from a config file, strings.ToUpper the value before assignment.
- Leave it empty to accept the driver default.
Example fix
// before
cfg.JournalMode = sqliteconfig.JournalMode("wal") // fails IsValid()
// after
cfg.JournalMode = sqliteconfig.JournalModeWAL Defensive patterns
Strategy: type-guard
Type guard
func validJournalMode(v sqliteconfig.JournalMode) bool {
switch v {
case sqliteconfig.JournalModeWAL,
sqliteconfig.JournalModeDelete,
sqliteconfig.JournalModeTruncate,
sqliteconfig.JournalModePersist,
sqliteconfig.JournalModeMemory,
sqliteconfig.JournalModeOff:
return true
}
return false
} Prevention
- Use the package's exported constants rather than raw strings.
- strings.ToUpper user input before assigning enum-typed config fields.
- Treat empty string as 'use default' rather than inventing a 'DEFAULT' value.
When it happens
Trigger: Setting JournalMode to something like 'wal' (lowercase), 'WRITE_AHEAD', or 'default' in a sqliteconfig.Config and calling Validate/ToURL. Only exact uppercase pragma strings from the JournalMode constants pass IsValid().
Common situations: Lowercase values in YAML/TOML configs that were never uppercased; users copying pragma names from SQLite docs with different spelling; typos.
Related errors
- path cannot be empty
- busy_timeout must be >= 0
- %w, got %d
- invalid config: %w
- wildcard (*) is not supported as SSH destination
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/1d67a2cda8b2f10a.
Report an issue: GitHub.