Describe the bug
object_store::aws::resolve_bucket_region always uses a virtual-hosted-style endpoint (src/aws/resolve.rs#L52):
let endpoint = format!("https://{bucket}.s3.amazonaws.com");
If the bucket name contains dots, the resulting hostname doesn't match S3's *.s3.amazonaws.com wildcard cert (a TLS wildcard only covers one DNS label), so the TLS handshake fails before any request is sent:
Generic S3 error: Error performing HEAD https://my.dotted.bucket.tbae8c3b8.s3.amazonaws.com in 30ms - HTTP error: error sending request
caused by: client error (Connect): invalid peer certificate: certificate not valid for name "my.dotted.bucket.tbae8c3b8.s3.amazonaws.com"
This is a documented AWS limitation: "the SSL wildcard certificate matches only buckets that do not contain dots". The rest of the crate is fine - AmazonS3Builder defaults to path-style - resolve_bucket_region is the only place the bucket name unconditionally ends up in the TLS hostname.
To Reproduce
object_store::aws::resolve_bucket_region("my.dotted.bucket.tbae8c3b8", &ClientOptions::new()).await
// => invalid peer certificate
Expected behavior
The region resolves. Path-style works for the same lookup - S3 returns x-amz-bucket-region either way (on 200/301/403):
$ curl -skI "https://s3.amazonaws.com/my.dotted.bucket.tbae8c3b8"
HTTP/1.1 301 Moved Permanently
x-amz-bucket-region: us-west-2
...
Server: AmazonS3
Fix can be simple - fall back to path-style when the bucket name contains dots (same heuristic the official AWS SDKs use):
let endpoint = if bucket.contains('.') {
format!("https://s3.amazonaws.com/{bucket}")
} else {
format!("https://{bucket}.s3.amazonaws.com")
};
Path-style deprecation isn't a concern here: AWS delayed it indefinitely, largely because dotted buckets have no virtual-hosted HTTPS alternative.
Happy to submit a PR.
Describe the bug
object_store::aws::resolve_bucket_regionalways uses a virtual-hosted-style endpoint (src/aws/resolve.rs#L52):If the bucket name contains dots, the resulting hostname doesn't match S3's
*.s3.amazonaws.comwildcard cert (a TLS wildcard only covers one DNS label), so the TLS handshake fails before any request is sent:This is a documented AWS limitation: "the SSL wildcard certificate matches only buckets that do not contain dots". The rest of the crate is fine -
AmazonS3Builderdefaults to path-style -resolve_bucket_regionis the only place the bucket name unconditionally ends up in the TLS hostname.To Reproduce
Expected behavior
The region resolves. Path-style works for the same lookup - S3 returns
x-amz-bucket-regioneither way (on 200/301/403):Fix can be simple - fall back to path-style when the bucket name contains dots (same heuristic the official AWS SDKs use):
Path-style deprecation isn't a concern here: AWS delayed it indefinitely, largely because dotted buckets have no virtual-hosted HTTPS alternative.
Happy to submit a PR.