dani-garcia/vaultwarden · error

Failed to parse global log level

Error message

Failed to parse global log level

What it means

init_logging parses the LOG_LEVEL config into a log::LevelFilter via from_str on the regex-captured global part. This error is returned when the captured string is not a valid log level (e.g. 'verbose', 'warn' misspelled, empty).

Solutions

  1. Set LOG_LEVEL to a valid level: off, error, warn, info, debug, or trace
  2. Use the override format for module granularity: LOG_LEVEL=info,vaultwarden::api::icons=debug
  3. Check for typos like 'warning' or 'verbose' in your .env / environment
  4. Check startup logs to see the exact invalid value echoed in the follow-up format error

Example fix

// before
LOG_LEVEL=warning
// after
LOG_LEVEL=warn
Defensive patterns

Strategy: validation

Validate before calling

const VALID = ['off','error','warn','info','debug','trace'];
const lvl = process.env.LOG_LEVEL?.split(',')[0].trim().toLowerCase();
if (lvl && !VALID.includes(lvl)) throw new Error(`Invalid LOG_LEVEL global level: ${lvl}. Use one of ${VALID.join('/')}`);

Type guard

function isValidLogLevel(s) { return ['off','error','warn','info','debug','trace'].includes(s.trim().toLowerCase()); }

Prevention

When it happens

Trigger: LOG_LEVEL set to a value matching the level regex prefix but whose first capture is not one of off/error/warn/info/debug/trace, e.g. LOG_LEVEL='verbose' or LOG_LEVEL='warning'.

Common situations: Users copying levels from other frameworks ('warning' instead of 'warn', 'verbose'); typos; setting LOG_LEVEL to a file path or arbitrary text.

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 dani-garcia/vaultwarden@cc67d644f6 (2026-09-19). Data as JSON: /api/errors/d212c2a9055da100. Report an issue: GitHub.

Appendix: source

Thrown at src/main.rs:246

        |   https://github.com/dani-garcia/vaultwarden/discussions or        |\n\
        |   https://vaultwarden.discourse.group/                             |\n\
        | Report suspected bugs/issues in the software itself at:            |\n\
        |   https://github.com/dani-garcia/vaultwarden/issues/new            |\n\
        \\--------------------------------------------------------------------/\n"
    );
}

fn init_logging() -> Result<log::LevelFilter, Error> {
    let levels = log::LevelFilter::iter().map(|lvl| lvl.as_str().to_lowercase()).collect::<Vec<String>>().join("|");
    let log_level_rgx_str = format!("^({levels})((,[^,=]+=({levels}))*)$");
    let log_level_rgx = regex::Regex::new(&log_level_rgx_str)?;
    let config_str = CONFIG.log_level().to_lowercase();

    let (level, levels_override) = if let Some(caps) = log_level_rgx.captures(&config_str) {
        let level = caps
            .get(1)
            .and_then(|m| log::LevelFilter::from_str(m.as_str()).ok())
            .ok_or(Error::new("Failed to parse global log level".to_owned(), ""))?;

        let levels_override: Vec<(&str, log::LevelFilter)> = caps
            .get(2)
            .map(|m| {
                m.as_str()
                    .split(',')
                    .collect::<Vec<&str>>()
                    .into_iter()
                    .filter_map(|s| match s.split_once('=') {
                        Some((log, lvl_str)) => log::LevelFilter::from_str(lvl_str).ok().map(|lvl| (log, lvl)),
                        _ => None,
                    })
                    .collect()
            })
            .ok_or(Error::new("Failed to parse overrides".to_owned(), ""))?;

        (level, levels_override)
    } else {

View on GitHub (pinned to cc67d644f6)