Skip to content

resolve_bucket_region fails TLS handshake for bucket names containing dots #747

Description

@brankogrb-db

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions