This is an automated email from the ASF dual-hosted git repository.
jtuglu1 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 4bc6a13d640 fix: retry S3 segment reads on transient SSLException (TLS
"Tag mismatch")
4bc6a13d640 is described below
commit 4bc6a13d640ecef337799d73726e64bc724341a4
Author: Adithya B Shetty <[email protected]>
AuthorDate: Tue Jun 23 13:12:58 2026 +0530
fix: retry S3 segment reads on transient SSLException (TLS "Tag mismatch")
S3Utils.S3RETRY recursed an SSLException into its non-IOException cause
(AEADBadTagException from a corrupted TLS record failing GCM auth),
classifying a transient transport failure as non-retriable. Under MSQ this
aborts the whole query. Treat SSLException as retriable, ahead of the
generic
IOException branch. Mirrors #11941.
---
.../java/org/apache/druid/storage/s3/S3Utils.java | 5 +++++
.../org/apache/druid/storage/s3/S3UtilsTest.java | 20 ++++++++++++++++++++
2 files changed, 25 insertions(+)
diff --git
a/extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/S3Utils.java
b/extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/S3Utils.java
index 82412fe412c..0c2546302a1 100644
---
a/extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/S3Utils.java
+++
b/extensions-core/s3-extensions/src/main/java/org/apache/druid/storage/s3/S3Utils.java
@@ -48,6 +48,7 @@ import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.model.S3Object;
import javax.annotation.Nullable;
+import javax.net.ssl.SSLException;
import java.io.File;
import java.io.IOException;
import java.net.URI;
@@ -77,6 +78,10 @@ public class S3Utils
{
if (e == null) {
return false;
+ } else if (e instanceof SSLException) {
+ // Transient TLS read failure (e.g. AEADBadTagException "Tag
mismatch!"). Retry here, ahead of
+ // the IOException branch, which would recurse into the
non-IOException crypto cause and not retry.
+ return true;
} else if (e instanceof IOException) {
if (e.getCause() != null) {
// Recurse with the underlying cause to see if it's retriable.
diff --git
a/extensions-core/s3-extensions/src/test/java/org/apache/druid/storage/s3/S3UtilsTest.java
b/extensions-core/s3-extensions/src/test/java/org/apache/druid/storage/s3/S3UtilsTest.java
index dcf7b3f8d0d..7d3135ca6bb 100644
---
a/extensions-core/s3-extensions/src/test/java/org/apache/druid/storage/s3/S3UtilsTest.java
+++
b/extensions-core/s3-extensions/src/test/java/org/apache/druid/storage/s3/S3UtilsTest.java
@@ -34,6 +34,8 @@ import
software.amazon.awssdk.services.s3.model.ObjectIdentifier;
import software.amazon.awssdk.services.s3.model.S3Error;
import software.amazon.awssdk.services.s3.model.S3Exception;
+import javax.crypto.AEADBadTagException;
+import javax.net.ssl.SSLException;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CompletionException;
@@ -59,6 +61,24 @@ public class S3UtilsTest
Assert.assertEquals(maxRetries, count.get());
}
+ @Test
+ public void testRetryWithSslExceptionWrappingAeadBadTag()
+ {
+ // Transient TLS "Tag mismatch!" should be retried, not treated as
terminal. See issue #19616.
+ final int maxRetries = 3;
+ final AtomicInteger count = new AtomicInteger();
+ Assert.assertThrows(
+ SSLException.class,
+ () -> S3Utils.retryS3Operation(
+ () -> {
+ count.incrementAndGet();
+ throw new SSLException("Tag mismatch!", new
AEADBadTagException("Tag mismatch!"));
+ },
+ maxRetries
+ ));
+ Assert.assertEquals(maxRetries, count.get());
+ }
+
@Test
public void testRetryWith4XXErrors()
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]