linera-io/linera-protocol · error
test-log: RUST_LOG_SPAN_EVENTS must be valid UTF-8
Error message
test-log: RUST_LOG_SPAN_EVENTS must be valid UTF-8
What it means
linera-storage-service configures tracing-subscriber span events from the RUST_LOG_SPAN_EVENTS variable (filters: new, enter, exit, close, active, full). It reads the variable with std::env::var_os, which returns an OsString because Unix environment variables are arbitrary bytes, then calls .to_str(); that returns None when the bytes are not valid UTF-8, and .expect() panics before the server starts. The 'test-log:' prefix comes from the well-known tokio test-log snippet this code follows.
Source
Thrown at linera-storage-service/src/server.rs:611
)]
async fn process_delete_all(&self, _request: Request<()>) -> Result<Response<()>, Status> {
self.delete_all().await?;
Ok(Response::new(()))
}
}
#[tokio::main]
async fn main() {
let env_filter = tracing_subscriber::EnvFilter::builder()
.with_default_directive(tracing_subscriber::filter::LevelFilter::INFO.into())
.from_env_lossy();
let internal_event_filter = {
match std::env::var_os("RUST_LOG_SPAN_EVENTS") {
Some(mut value) => {
value.make_ascii_lowercase();
let value = value
.to_str()
.expect("test-log: RUST_LOG_SPAN_EVENTS must be valid UTF-8");
value
.split(',')
.map(|filter| match filter.trim() {
"new" => FmtSpan::NEW,
"enter" => FmtSpan::ENTER,
"exit" => FmtSpan::EXIT,
"close" => FmtSpan::CLOSE,
"active" => FmtSpan::ACTIVE,
"full" => FmtSpan::FULL,
_ => panic!("test-log: RUST_LOG_SPAN_EVENTS must contain filters separated by `,`.\n\t\
For example: `active` or `new,close`\n\t\
Supported filters: new, enter, exit, close, active, full\n\t\
Got: {value}"),
})
.fold(FmtSpan::NONE, |acc, filter| filter | acc)
}
None => FmtSpan::NONE,
}View on GitHub (pinned to 6c226ddcb3)
Solutions
- Re-set the variable to plain ASCII filters: export RUST_LOG_SPAN_EVENTS="new,close"
- Or unset it entirely: None selects FmtSpan::NONE and the server starts normally
- Find the offending bytes with `printf '%s' "$RUST_LOG_SPAN_EVENTS" | od -c` and look for non-ASCII byte sequences
- Re-save the script/.env/CI variable definition as UTF-8
Example fix
# before: .env saved as latin-1, RUST_LOG_SPAN_EVENTS="café,close" carries 0xE9 bytes -> panic # after: UTF-8 file, or ASCII-only value export RUST_LOG_SPAN_EVENTS="new,close"
Defensive patterns
Strategy: validation
Validate before calling
// Rust launcher: use var() (UTF-8 checked) instead of var_os before spawning the server
match std::env::var("RUST_LOG_SPAN_EVENTS") {
Ok(v) => { /* safe: guaranteed valid UTF-8 */ }
Err(std::env::VarError::NotUnicode(_)) => { /* clear the variable or abort with a clear message */ }
Err(std::env::VarError::NotPresent) => {}
} Prevention
- Keep RUST_LOG_SPAN_EVENTS to ASCII filter names (new, enter, exit, close, active, full)
- Save .env and CI variable files as UTF-8
- In your own code prefer std::env::var over var_os when a String is required: it returns NotUnicode instead of raw bytes
When it happens
Trigger: Starting linera-storage-service with RUST_LOG_SPAN_EVENTS whose raw bytes are non-UTF-8: a latin-1 encoded accented character, a stray 0x80-0xFF byte, or a value injected from a script or .env file saved in a legacy encoding. Pure-ASCII values like `new,close` never trigger it.
Common situations: Values written by older Windows shells or PowerShell in a legacy code page; .env files saved by a non-UTF-8 editor; CI variables pasted from rich text with invisible non-UTF-8 bytes; Docker ENV injected from a binary file.
Related errors
- Invalid RUST_LOG_FORMAT: `{format}`. Valid values are `json
- test-log: RUST_LOG_SPAN_EVENTS must contain filters separate
- Failed to set up SIGINT handler
- Failed to set up SIGTERM handler
- Failed to set up SIGHUP handler
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/276f0e8969662e4d.
Report an issue: GitHub.