cloudflare/pingora · error · std::io::Error
dial9 s3 service_name must not be empty
Error message
dial9 s3 service_name must not be empty
What it means
Companion check to the bucket validation in build_dial9_runtime() (pingora-runtime/src/lib.rs:371): with the dial9-worker-s3 feature and s3_upload configured, the service_name used for S3 request signing must be a non-empty string after trimming. An empty service name would make signing ambiguous, so construction returns ErrorKind::InvalidInput.
Source
Thrown at pingora-runtime/src/lib.rs:371
let mut traced = TracedRuntime::builder()
.with_trace_path(opts.trace_path.clone())
.with_runtime_name(runtime_name)
.with_task_tracking(opts.task_tracking);
if let Some(worker_poll_interval) = opts.worker_poll_interval {
traced = traced.with_worker_poll_interval(worker_poll_interval);
}
#[cfg(feature = "dial9-worker-s3")]
if let Some(s3_upload) = &opts.s3_upload {
if s3_upload.bucket.trim().is_empty() {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"dial9 s3 bucket must not be empty",
));
}
if s3_upload.service_name.trim().is_empty() {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"dial9 s3 service_name must not be empty",
));
}
let s3_config = dial9_tokio_telemetry::background_task::s3::S3Config::builder()
.bucket(s3_upload.bucket.clone())
.service_name(s3_upload.service_name.clone())
.maybe_prefix(s3_upload.prefix.clone())
.maybe_region(s3_upload.region.clone())
.maybe_instance_path(s3_upload.instance_path.clone());
let traced = traced.with_s3_uploader(s3_config.build());
if let Some(client) = s3_upload.client.clone() {
return traced
.with_s3_client(client)
.build_and_start(builder, writer);
}
return traced.build_and_start(builder, writer);
}View on GitHub (pinned to 0046038bd4)
Solutions
- Set service_name explicitly, normally "s3" for AWS S3 and S3-compatible stores
- For non-AWS endpoints keep "s3" unless the provider documents otherwise
- Validate bucket + service_name as a pair wherever S3 upload config is parsed
Example fix
// before
s3_upload: Some(S3Upload { bucket: "my-trace-bucket".into(), service_name: String::new(), ..Default::default() })
// after
s3_upload: Some(S3Upload { bucket: "my-trace-bucket".into(), service_name: "s3".into(), ..Default::default() }) Defensive patterns
Strategy: validation
Validate before calling
if let Some(s3) = &opts.s3_upload {
if s3.service_name.trim().is_empty() {
return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "s3 service_name must be set"));
}
} Prevention
- Default service_name to "s3" in your config layer when the S3 block is enabled
- Validate bucket and service_name as a pair wherever the S3 upload config is parsed
- Cover the S3 block with a config unit test so blank fields never reach the runtime build
When it happens
Trigger: Dial9RuntimeOpts with s3_upload = Some(...) where service_name is empty or whitespace, under the dial9-worker-s3 feature; validated at dial9 runtime construction right after the bucket check.
Common situations: S3 block configured with only bucket/region while service_name was assumed to default; non-AWS endpoints (MinIO etc.) where the field seems irrelevant but is still required; config templating that omits the key.
Related errors
- dial9 s3 bucket must not be empty
- dial9 max_file_size must be greater than zero
- 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
AI-assisted analysis of cloudflare/pingora@0046038bd4 (2026-08-16).
Data as JSON: /api/errors/31cf02bb05ba3fc6.
Report an issue: GitHub.