{"record":{"id":"e2731877eb5bff2b","repo":"cloudflare/pingora","slug":"dial9-max-file-size-must-be-less-than-or-equal-to","errorCode":null,"errorMessage":"dial9 max_file_size must be less than or equal to max_total_size","messagePattern":"dial9 max_file_size must be less than or equal to max_total_size","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"pingora-runtime/src/lib.rs","lineNumber":331,"sourceCode":"    dial9_tokio_telemetry::telemetry::TelemetryGuard,\n)> {\n    use dial9_tokio_telemetry::telemetry::{RotatingWriter, TracedRuntime};\n    use std::io::{Error, ErrorKind};\n\n    if opts.max_file_size == 0 {\n        return Err(Error::new(\n            ErrorKind::InvalidInput,\n            \"dial9 max_file_size must be greater than zero\",\n        ));\n    }\n    if opts.max_total_size == 0 {\n        return Err(Error::new(\n            ErrorKind::InvalidInput,\n            \"dial9 max_total_size must be greater than zero\",\n        ));\n    }\n    if opts.max_file_size > opts.max_total_size {\n        return Err(Error::new(\n            ErrorKind::InvalidInput,\n            \"dial9 max_file_size must be less than or equal to max_total_size\",\n        ));\n    }\n    if opts.worker_poll_interval == Some(Duration::ZERO) {\n        return Err(Error::new(\n            ErrorKind::InvalidInput,\n            \"dial9 worker_poll_interval must be greater than zero\",\n        ));\n    }\n\n    if let Some(parent) = opts.trace_path.parent() {\n        std::fs::create_dir_all(parent)?;\n    }\n\n    let writer = RotatingWriter::builder()\n        .base_path(opts.trace_path.clone())\n        .max_file_size(opts.max_file_size)","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/cloudflare/pingora/blob/0046038bd402bc82912da862dadf9a479f31e9f1/pingora-runtime/src/lib.rs#L313-L349","documentation":"build_dial9_runtime() (pingora-runtime/src/lib.rs:331) requires max_file_size <= max_total_size: a single rotating trace file must always fit inside the total trace budget. If the per-file cap exceeds the total, runtime construction returns ErrorKind::InvalidInput with 'dial9 max_file_size must be less than or equal to max_total_size'.","triggerScenarios":"Dial9RuntimeOpts where max_file_size > max_total_size, e.g. per-file 2 GiB with a 1 GiB total budget; usually a units mismatch (MiB vs GiB) or independent edits of two config keys.","commonSituations":"Tuning the per-file size without re-tuning the total; config defaults where the file size was raised over time but the budget stayed; unit confusion between binary and decimal multipliers.","solutions":["Raise max_total_size to at least max_file_size (preferably a multiple covering several rotation generations)","Define the two values from one source, e.g. total = file_size * N_FILES, so they can never invert","Add a config sanity test that fails when file > total"],"exampleFix":"// before\nlet opts = Dial9RuntimeOpts { max_file_size: 4 << 30, max_total_size: 1 << 30, ..Default::default() };\n\n// after\nlet opts = Dial9RuntimeOpts { max_file_size: 64 << 20, max_total_size: 4 << 30, ..Default::default() };","handlingStrategy":"validation","validationCode":"if opts.max_file_size > opts.max_total_size {\n    return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput,\n        format!(\"per-file {} exceeds total {}\", opts.max_file_size, opts.max_total_size)));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive both sizes from a single source constant so they cannot invert","Log the effective pair at startup for quick diagnosis","Add a config sanity test asserting file <= total"],"tags":["rust","pingora-runtime","dial9","log-rotation","config-validation"],"backgroundTag":"invalid-config-value","analyzedSha":"0046038bd402bc82912da862dadf9a479f31e9f1","analyzedAt":"2026-08-16T21:33:22.341Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}