diff --git a/src/IO/S3/Client.cpp b/src/IO/S3/Client.cpp index 5fe470f9c19f..a248bfcd7382 100644 --- a/src/IO/S3/Client.cpp +++ b/src/IO/S3/Client.cpp @@ -703,19 +703,35 @@ Client::doRequest(RequestType & request, RequestFn request_fn) const continue; } - if (error.GetResponseCode() != Aws::Http::HttpResponseCode::MOVED_PERMANENTLY) + /// IllegalLocationConstraintException may indicate that we are working with an opt-in region (e.g. me-south-1) + /// In that case, we need to update the region and try again + bool is_illegal_constraint_exception = error.GetExceptionName() == "IllegalLocationConstraintException"; + if (error.GetResponseCode() != Aws::Http::HttpResponseCode::MOVED_PERMANENTLY && !is_illegal_constraint_exception) return result; // maybe we detect a correct region - if (!detect_region) + bool new_region_detected = false; + if (!detect_region || is_illegal_constraint_exception) { if (auto region = GetErrorMarshaller()->ExtractRegion(error); !region.empty() && region != explicit_region) { + LOG_INFO(log, "Detected new region: {}", region); request.overrideRegion(region); insertRegionOverride(bucket, region); + new_region_detected = true; } } + /// special handling for opt-in regions + if (new_region_detected && is_illegal_constraint_exception && initial_endpoint.substr(11) == "amazonaws.com") + { + S3::URI new_uri(initial_endpoint); + new_uri.addRegionToURI(request.getRegionOverride()); + found_new_endpoint = true; + request.overrideURI(new_uri); + continue; + } + // we possibly got new location, need to try with that one auto new_uri = getURIFromError(error); if (!new_uri)