risingwavelabs/risingwave · critical
failed to parse `RUST_LOG`
Error message
failed to parse `RUST_LOG`
What it means
init_risingwave_logger reads RUST_LOG and parses it with tracing_subscriber's `Targets` filter; `.expect("failed to parse `RUST_LOG`")` panics when the string is not a valid directive list. Valid syntax is comma-separated `target=level` pairs like `info,rw_stream=debug,tower=warn`.
Solutions
- Fix RUST_LOG to valid directive syntax, e.g. RUST_LOG=info,risingwave_stream=debug.
- Use only valid level names: error, warn, info, debug, trace (or plain module filter without level).
- Unset RUST_LOG to fall back to the built-in default filter.
- Test the filter in a small Rust snippet using Targets::from_str before deploying.
Example fix
// before (invalid directive) RUST_LOG=verbose,rw_stream=debg // after RUST_LOG=info,rw_stream=debug
Defensive patterns
Strategy: validation
Validate before calling
// Validate RUST_LOG syntax before launching
if let Ok(v) = std::env::var("RUST_LOG") {
let valid_levels = ["error", "warn", "info", "debug", "trace"];
for directive in v.split(',') {
let level = directive.rsplit('=').next().unwrap_or(directive);
assert!(
directive.is_empty() || valid_levels.contains(&level) || !level.contains(|c: char| c.is_whitespace()),
"invalid RUST_LOG directive: {directive}"
);
}
} Prevention
- Prefer simple forms like RUST_LOG=info or RUST_LOG=info,crate=debug.
- Test the directive locally with a trivial tracing example before shipping.
- Leave RUST_LOG unset and use config-file log levels when unsure.
When it happens
Trigger: RUST_LOG set (and non-empty) with invalid directives — e.g. `RUST_LOG=trace,` malformed level names (`RUST_LOG=infos`), missing level (`rw=dd`), stray characters, or invalid target syntax.
Common situations: Typos in level names (verbose, warnning); pasting regex or log4j-style patterns; commas/semicolons mix-ups; invalid module paths; users attempting per-crate filters with unsupported syntax.
Understand the failure class
Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to create directory
- Failed to parse RW_DEADLOCK_DETECTION
- {0}
- AZBLOB_ENDPOINT not found from environment variables
- Can't cast string to date (expected format is YYYY-MM-DD)
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/604f41247e6f9b37.
Report an issue: GitHub.
Appendix: source
Thrown at src/utils/runtime/src/logger.rs:312
Level::DEBUG
} else {
Level::INFO
}
}
};
filter = filter.with_default(default_level);
// Overrides from settings.
filter = filter.with_targets(settings.targets);
if let Some(default_level) = settings.default_level {
filter = filter.with_default(default_level);
}
// Overrides from env var.
if let Ok(rust_log) = std::env::var(EnvFilter::DEFAULT_ENV)
&& !rust_log.is_empty()
{
let rust_log_targets: Targets = rust_log.parse().expect("failed to parse `RUST_LOG`");
if let Some(default_level) = rust_log_targets.default_level() {
filter = filter.with_default(default_level);
}
filter = filter.with_targets(rust_log_targets)
};
filter
};
let mut layers = vec![];
// fmt layer (formatting and logging to `stdout` or `stderr`)
{
let fmt_layer = tracing_subscriber::fmt::layer()
.with_thread_names(settings.with_thread_name)
.with_timer(default_timer.clone())
.with_ansi(settings.colorful)
.with_writer(move || {View on GitHub (pinned to 6469eb736d)