cloudflare/pingora · error · std::io::Error
dial9 max_file_size must be greater than zero
Error message
dial9 max_file_size must be greater than zero
What it means
build_dial9_runtime() in pingora-runtime validates Dial9RuntimeOpts before constructing the dial9 traced Tokio runtime that writes rotating trace files. max_file_size is the per-file cap of the rotating trace writer, and 0 is rejected up front with ErrorKind::InvalidInput. The error is returned (not a panic) at runtime construction time, so it fails fast during startup.
Source
Thrown at pingora-runtime/src/lib.rs:319
#[cfg(not(tokio_unstable))]
let _ = (builder, opts);
}
#[cfg(feature = "dial9")]
fn build_dial9_runtime(
builder: Builder,
runtime_name: &str,
opts: &Dial9RuntimeOpts,
) -> std::io::Result<(
tokio::runtime::Runtime,
dial9_tokio_telemetry::telemetry::TelemetryGuard,
)> {
use dial9_tokio_telemetry::telemetry::{RotatingWriter, TracedRuntime};
use std::io::{Error, ErrorKind};
if opts.max_file_size == 0 {
return Err(Error::new(
ErrorKind::InvalidInput,
"dial9 max_file_size must be greater than zero",
));
}
if opts.max_total_size == 0 {
return Err(Error::new(
ErrorKind::InvalidInput,
"dial9 max_total_size must be greater than zero",
));
}
if opts.max_file_size > opts.max_total_size {
return Err(Error::new(
ErrorKind::InvalidInput,
"dial9 max_file_size must be less than or equal to max_total_size",
));
}
if opts.worker_poll_interval == Some(Duration::ZERO) {
return Err(Error::new(View on GitHub (pinned to 0046038bd4)
Solutions
- Set max_file_size to a positive size in bytes (e.g. 64 * 1024 * 1024 per trace file)
- Satisfy the sibling checks in the same validation block: max_total_size > 0, max_file_size <= max_total_size, worker_poll_interval None or positive
- Populate these fields from a validated config loader instead of raw optional deserialization
Example fix
// before
let opts = Dial9RuntimeOpts { max_file_size: 0, max_total_size: 1 << 30, ..Default::default() };
// after
let opts = Dial9RuntimeOpts { max_file_size: 64 << 20, max_total_size: 1 << 30, ..Default::default() }; Defensive patterns
Strategy: validation
Validate before calling
// Mirror the library's checks at config-load time
fn validate_dial9(opts: &Dial9RuntimeOpts) -> std::io::Result<()> {
if opts.max_file_size == 0 {
return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "max_file_size must be > 0"));
}
if opts.max_total_size == 0 {
return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "max_total_size must be > 0"));
}
if opts.max_file_size > opts.max_total_size {
return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "max_file_size must be <= max_total_size"));
}
Ok(())
} Prevention
- Give dial9 size fields explicit non-zero defaults in your config layer
- Reject 0 values at config load with a clear message naming the field
- Unit-test your config parsing against the same constraints pingora-runtime enforces
When it happens
Trigger: Building the dial9 traced runtime through pingora-runtime with Dial9RuntimeOpts { max_file_size: 0, .. }, typically because the field was left at its zero default or a config file supplied 0.
Common situations: Wiring Dial9RuntimeOpts from YAML/env where max_file_size was forgotten; a config schema change that stopped populating the field; copy-pasting an options struct literal with placeholder zeros.
Related errors
- dial9 max_total_size must be greater than zero
- dial9 max_file_size must be less than or equal to max_total_
- dial9 worker_poll_interval must be greater than zero
- dial9 s3 bucket must not be empty
- dial9 s3 service_name must not be empty
AI-assisted analysis of cloudflare/pingora@0046038bd4 (2026-08-16).
Data as JSON: /api/errors/f10ceca4da7bc19d.
Report an issue: GitHub.