{"record":{"id":"ee4cd6147cbc0b82","repo":"cloudflare/pingora","slug":"dial9-s3-bucket-must-not-be-empty","errorCode":null,"errorMessage":"dial9 s3 bucket must not be empty","messagePattern":"dial9 s3 bucket must not be empty","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"pingora-runtime/src/lib.rs","lineNumber":365,"sourceCode":"    let writer = RotatingWriter::builder()\n        .base_path(opts.trace_path.clone())\n        .max_file_size(opts.max_file_size)\n        .max_total_size(opts.max_total_size)\n        .maybe_rotation_period(opts.rotation_period)\n        .build()?;\n\n    let mut traced = TracedRuntime::builder()\n        .with_trace_path(opts.trace_path.clone())\n        .with_runtime_name(runtime_name)\n        .with_task_tracking(opts.task_tracking);\n    if let Some(worker_poll_interval) = opts.worker_poll_interval {\n        traced = traced.with_worker_poll_interval(worker_poll_interval);\n    }\n\n    #[cfg(feature = \"dial9-worker-s3\")]\n    if let Some(s3_upload) = &opts.s3_upload {\n        if s3_upload.bucket.trim().is_empty() {\n            return Err(std::io::Error::new(\n                std::io::ErrorKind::InvalidInput,\n                \"dial9 s3 bucket must not be empty\",\n            ));\n        }\n        if s3_upload.service_name.trim().is_empty() {\n            return Err(std::io::Error::new(\n                std::io::ErrorKind::InvalidInput,\n                \"dial9 s3 service_name must not be empty\",\n            ));\n        }\n        let s3_config = dial9_tokio_telemetry::background_task::s3::S3Config::builder()\n            .bucket(s3_upload.bucket.clone())\n            .service_name(s3_upload.service_name.clone())\n            .maybe_prefix(s3_upload.prefix.clone())\n            .maybe_region(s3_upload.region.clone())\n            .maybe_instance_path(s3_upload.instance_path.clone());\n        let traced = traced.with_s3_uploader(s3_config.build());\n        if let Some(client) = s3_upload.client.clone() {","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/cloudflare/pingora/blob/0046038bd402bc82912da862dadf9a479f31e9f1/pingora-runtime/src/lib.rs#L347-L383","documentation":"When pingora-runtime is built with the dial9-worker-s3 feature and opts.s3_upload is Some, build_dial9_runtime() validates the S3 upload settings before wiring the background uploader (lib.rs:365). The bucket name is trimmed and must be non-empty, otherwise construction returns ErrorKind::InvalidInput with 'dial9 s3 bucket must not be empty'.","triggerScenarios":"Dial9RuntimeOpts with s3_upload = Some(S3Upload { bucket: \"\" or \"   \", .. }) while the dial9-worker-s3 feature is compiled in; the check runs during dial9 runtime construction at startup.","commonSituations":"S3 upload enabled in config but the bucket key left blank; bucket populated from an env var that is unset in the environment being deployed; whitespace-only values from templated config files.","solutions":["Set a real bucket name, e.g. bucket: \"my-trace-bucket\".to_string()","Also set a non-empty service_name (checked immediately after) and prefer explicit region/credentials configuration","Fail config loading early when the S3 block is present but bucket/service_name are blank"],"exampleFix":"// before\ns3_upload: Some(S3Upload { bucket: String::new(), service_name: \"s3\".into(), ..Default::default() })\n\n// after\ns3_upload: Some(S3Upload { bucket: \"my-trace-bucket\".into(), service_name: \"s3\".into(), ..Default::default() })","handlingStrategy":"validation","validationCode":"if let Some(s3) = &opts.s3_upload {\n    if s3.bucket.trim().is_empty() {\n        return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, \"s3 bucket must be set\"));\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Fail config loading when the S3 upload block exists but bucket is blank","Resolve the bucket from an env var with a required-value check, not a silent empty default","Trim and assert both bucket and service_name together before building the runtime"],"tags":["rust","pingora-runtime","dial9","s3","config-validation"],"backgroundTag":"s3-misconfiguration","analyzedSha":"0046038bd402bc82912da862dadf9a479f31e9f1","analyzedAt":"2026-08-16T21:33:22.341Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}