dani-garcia/vaultwarden · error · Error
Failed to parse global log level
Error message
Failed to parse global log level
What it means
init_logging() runs at startup and validates CONFIG.log_level() (LOG_LEVEL env) against a regex assembled from valid level names off|error|warn|info|debug|trace plus optional ',target=level' overrides. After a successful regex match, capture group 1 (the global level) must parse via log::LevelFilter::from_str; this error fires when it does not, aborting startup with a wrapped crate::Error. Because the config string is lowercased first and log's FromStr is case-insensitive, this branch is defensive and effectively unreachable — malformed values almost always fail the regex and get the sibling 'LOG_LEVEL should follow the format...' error instead.
Source
Thrown at src/main.rs:248
| 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 0cefa4cca7)
Solutions
- Set LOG_LEVEL to a valid form: LOG_LEVEL=info or LOG_LEVEL=info,vaultwarden::api::icons=debug
- Remove surrounding quotes, stray spaces, and empty segments from the env value
- Unset LOG_LEVEL to fall back to the default and restart, confirming the rest of the config is fine
- If running a custom build, verify every regex token is a string log::LevelFilter::from_str accepts
Example fix
# before LOG_LEVEL="Info, vaultwarden::api::icons=Debug " # after LOG_LEVEL=info,vaultwarden::api::icons=debug
Defensive patterns
Strategy: validation
Validate before calling
# Validate LOG_LEVEL before starting the server
python3 - <<'EOF'
import os, re, sys
lvl = r'off|error|warn|info|debug|trace'
v = os.environ.get('LOG_LEVEL', 'info').strip().lower()
if not re.fullmatch(rf'({lvl})((,[^,=]+=({lvl}))*)', v):
print('LOG_LEVEL must look like: info,vaultwarden::api::icons=debug')
sys.exit(1)
EOF Type guard
fn is_valid_log_level(s: &str) -> bool {
let lvl = r"off|error|warn|info|debug|trace";
regex::Regex::new(&format!("^({lvl})((,[^,=]+=({lvl}))*)$")).unwrap().is_match(&s.to_lowercase())
} Prevention
- Use only off|error|warn|info|debug|trace as levels
- Write overrides as module=level with no spaces
- Add a pre-start config lint for LOG_LEVEL in container entrypoints
- Lowercase the value in deployment tooling to match the parser
When it happens
Trigger: A LOG_LEVEL whose first token satisfies the generated regex yet fails LevelFilter::from_str — practically impossible in stock builds since the regex only admits valid level names; realistic only in forks that alter the regex or the level source of truth.
Common situations: Typos in LOG_LEVEL (these usually hit the sibling format error instead); docker-compose values with quotes or trailing whitespace; custom builds that extend the regex with tokens that from_str rejects.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse overrides
- ConfigInvalid
- Can't convert to number
- Error saving API key
- Error saving attachment
AI-assisted analysis of dani-garcia/vaultwarden@0cefa4cca7 (2026-08-16).
Data as JSON: /api/errors/d212c2a9055da100.
Report an issue: GitHub.