cloudflare/pingora · error · std::io::Error

dial9 max_total_size must be greater than zero

Error message

dial9 max_total_size must be greater than zero

What it means

The second validation in build_dial9_runtime() (pingora-runtime/src/lib.rs:325): the total on-disk budget for all dial9 trace files, max_total_size, must be greater than zero. A zero budget would mean the rotating writer could never write a file, so construction returns ErrorKind::InvalidInput instead.

Source

Thrown at pingora-runtime/src/lib.rs:325

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(
            ErrorKind::InvalidInput,
            "dial9 worker_poll_interval must be greater than zero",
        ));
    }

    if let Some(parent) = opts.trace_path.parent() {

View on GitHub (pinned to 0046038bd4)

Solutions

  1. Set max_total_size to a positive byte budget at least as large as max_file_size (e.g. keep 10-20x the per-file size)
  2. If the intent was unlimited growth, pick a large explicit cap instead of 0
  3. Validate both size fields together at config-load time so the pair is consistent

Example fix

// before
let opts = Dial9RuntimeOpts { max_file_size: 64 << 20, max_total_size: 0, ..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

if opts.max_total_size == 0 {
    return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput,
        format!("dial9 max_total_size must be > 0, got {}", opts.max_total_size)));
}

Prevention

When it happens

Trigger: Constructing the dial9 traced runtime with Dial9RuntimeOpts { max_total_size: 0, .. } while max_file_size itself is positive; the check runs right after the max_file_size check.

Common situations: Setting only max_file_size in config and leaving the total unset; config templates where the total-budget key was renamed or dropped; disabling rotation by setting the total to 0 (not supported).

Related errors


AI-assisted analysis of cloudflare/pingora@0046038bd4 (2026-08-16). Data as JSON: /api/errors/29bc4c43dc05b480. Report an issue: GitHub.