nautechsystems/nautilus_trader · error · anyhow::Error
Invalid log level: {v}
Error message
Invalid log level: {v} What it means
`parse_level` (crates/common/src/logging/config.rs) converts a spec string into a tracing LevelFilter using FromStr, and maps any parse failure to this error. It exists so bad log-level strings in env vars or config specs surface a clear message naming the offending value.
Source
Thrown at crates/common/src/logging/config.rs:296
/// # Errors
///
/// Returns an error if the variable is unset or contains invalid syntax.
pub fn from_env() -> anyhow::Result<Self> {
let spec = env::var("NAUTILUS_LOG")?;
Self::from_spec(&spec)
}
}
/// Parses a boolean value from a string.
///
/// Returns `true` unless the value is explicitly "false", "0", or "no" (case-insensitive).
fn parse_bool_value(v: &str) -> bool {
!matches!(v.to_lowercase().as_str(), "false" | "0" | "no")
}
/// Parses a log level from a string.
fn parse_level(v: &str) -> anyhow::Result<LevelFilter> {
LevelFilter::from_str(v).map_err(|_| anyhow::anyhow!("Invalid log level: {v}"))
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use super::*;
use crate::config::ConfigError;
#[rstest]
fn test_zero_rotation_max_file_size_rejected() {
let file_config = FileWriterConfig::new(None, None, None, Some((0, 5)));
let result = LoggerConfig::builder().file_config(file_config).build();
assert!(
matches!(result, Err(ConfigError::Range { field, .. }) if field == "file_config.file_rotate.max_file_size")
);
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Use one of the accepted levels: trace, debug, info, warn, error, off (case-insensitive).
- Map Python-style names before passing: WARNING->WARN, CRITICAL->ERROR.
- Trim whitespace/quotes from the env/config value and check spec separators (';' component=LEVEL pairs).
- Log or echo the failing spec value and validate at startup before launching the node.
Example fix
// before
NAUTILUS_LOG="warning" // parse_level fails
// after
NAUTILUS_LOG="warn" // or map: let level = match s {"WARNING"=>"WARN", s=>s}; Defensive patterns
Strategy: validation
Validate before calling
// Rust: validate level before building the config
const LEVELS: [&str; 6] = ["trace","debug","info","warn","error","off"];
assert!(LEVELS.contains(&level.to_lowercase().as_str()), "invalid level {level}"); Type guard
fn parse_level_or(v: &str, default: LevelFilter) -> LevelFilter {
LevelFilter::from_str(v).unwrap_or(default)
} Try / catch
match parse_level(spec) {
Ok(l) => l,
Err(e) => { eprintln!("fix NAUTILUS_LOG: {e}; use trace|debug|info|warn|error|off"); std::process::exit(2); }
} Prevention
- Memorize the accepted set: trace, debug, info, warn, error, off.
- Translate Python/logging-framework level names before passing them in.
- Validate log specs at startup with a clear CLI check, before node launch.
- Avoid quotes/whitespace leaking into env values from shell wrappers.
When it happens
Trigger: Passing a level string that is not one of TRACE/DEBUG/INFO/WARN/ERROR/OFF (case accepted by tracing, plus lowercase variants) to the logging spec — e.g. NAUTILUS_LOG levels segment set to "verbose", "warning", "LOG_INFO", "" or "info;" with stray punctuation.
Common situations: Copying Python logging level names ("WARNING", "CRITICAL") or syslog names into the spec; typos like "DEBG"; env var containing whitespace or quotes from shell escaping; a component name accidentally parsed as a level in the spec string.
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
- Invalid log level string: '{s}'
- Component log level for '{key}' must be a string, was: {valu
- Unsupported blockchain {blockchain} for RPC connection
- Kraken Spot does not support the demo environment
- Invalid scientific notation exponent '{exponent}': must be a
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/dbbc100ea8f36e9b.
Report an issue: GitHub.