Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

BigQueryException: Connection has closed: javax.net.ssl.SSLException: Connection reset

Hi team, 

My view has ~100M records and I have a requirement to read it in Java code and process it. I'm using the below code

TableId destinationTableId = TableId.of("my_project","my_dataset","destination_table");
String query = "select col1, col2,..coln from my_project.my_dataset.my_view";
QueryJobConfiguration.Builder builder = QueryJobConfiguration.newBuilder(query)
.setUseLegacySql(false)
.setDestinationTable(destinationTableId)
.setCreateSession(false)
.setConnectionProperties(
List.of(
(ConnectionProperty.newBuilder()
.setKey("session_id")
.setValue("prev_session_id") // We save session_id from a previous query. It'll be just few minutes old
.build())));

JobId jobId = JobId.newBuilder().setLocation("US").setJob(UUID.randomUUID().toString()).build(); // My dataset is in US multi-region
Job queryJob = bigQuery.create(JobInfo.newBuilder(builder.build()).setJobId(jobId).build());
TableResult tableResult;
try {
queryJob = queryJob.waitFor();
if (queryJob == null) {
throw new RuntimeException("Job no longer exists");
}

tableResult = queryJob.getQueryResults();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} catch(BigQueryException exp ){
throw exp;
}

for (FieldValueList record : tableResult.iterateAll()) {
// process record
}

The query succeeds and returns table result but I'm  seeing com.google.cloud.bigquery.BigQueryException: Connection has closed: javax.net.ssl.SSLException: Connection reset while iterating through all the records. This error occurs sometimes after 3 hours, sometimes after 6 hours and sometimes within an hour.
What should I do to resolve the issue?
Thanks

Artifacts: 

com.google.cloud:google-cloud-bigquery:2.5.1
Java 17

 

0 3 1,398
3 REPLIES 3

Error stack trace is as below


Caused by: javax.net.ssl.SSLException: Connection has closed: javax.net.ssl.SSLException: Connection reset
at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.checkEOF(SSLSocketImpl.java:1163)
at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:1008)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:244)
at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:284)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:343)
at java.base/sun.net.www.http.ChunkedInputStream.readAheadBlocking(ChunkedInputStream.java:554)
at java.base/sun.net.www.http.ChunkedInputStream.readAhead(ChunkedInputStream.java:611)
at java.base/sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:705)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:132)
at java.base/sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3711)
at com.google.api.client.http.javanet.NetHttpResponse$SizeValidatingInputStream.read(NetHttpResponse.java:164)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:132)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:106)
at com.google.common.io.ByteStreams.exhaust(ByteStreams.java:296)

 

.api.client.http.ConsumingInputStream.close(ConsumingInputStream.java:40) 
at java.base/java.io.FilterInputStream.close(FilterInputStream.java:179)
at java.base/java.util.zip.InflaterInputStream.close(InflaterInputStream.java:231)
at java.base/java.util.zip.GZIPInputStream.close(GZIPInputStream.java:136)
at java.base/java.io.BufferedInputStream.close(BufferedInputStream.java:481)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._closeInput(UTF8StreamJsonParser.java:292)
at com.fasterxml.jackson.core.base.ParserBase.close(ParserBase.java:392)
at com.google.api.client.json.jackson2.JacksonParser.close(JacksonParser.java:48)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:363)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:335)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:79)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:73)
at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:460)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:565)
at com.google.cloud.bigquery.spi.v2.HttpBigQueryRpc.listTableData(HttpBigQueryRpc.java:512)
at com.google.cloud.bigquery.BigQueryImpl$29.call(BigQueryImpl.java:1114)
at com.google.cloud.bigquery.BigQueryImpl$29.call(BigQueryImpl.java:1109)
at com.google.api.gax.retrying.DirectRetryingExecutor.submit(DirectRetryingExecutor.java:103)
at com.google.cloud.RetryHelper.run(RetryHelper.java:76)
at com.google.cloud.RetryHelper.runWithRetries(RetryHelper.java:50)
at com.google.cloud.bigquery.BigQueryImpl.listTableData(BigQueryImpl.java:1108)
at com.google.cloud.bigquery.BigQueryImpl.access$500(BigQueryImpl.java:58)
at com.google.cloud.bigquery.BigQueryImpl$TableDataPageFetcher.getNextPage(BigQueryImpl.java:198)
at com.google.cloud.PageImpl.getNextPage(PageImpl.java:116)
at com.google.cloud.PageImpl$PageIterator.computeNext(PageImpl.java:66)
at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:145)
at com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:140)
at com.google.common.collect.TransformedIterator.hasNext(TransformedIterator.java:46)
// stack trace for my code
Caused by: javax.net.ssl.SSLException: Connection reset
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:127)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:378)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:316)
at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1704)
at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:1085)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:244)
at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:284)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:343)
at java.base/sun.net.www.http.ChunkedInputStream.readAheadBlocking(ChunkedInputStream.java:554)
at java.base/sun.net.www.http.ChunkedInputStream.readAhead(ChunkedInputStream.java:611)
at java.base/sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:705)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:132)
at java.base/sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3711)
at com.google.api.client.http.javanet.NetHttpResponse$SizeValidatingInputStream.read(NetHttpResponse.java:164)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:132)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:132)

 

a.util.zip.InflaterInputStream.fill(InflaterInputStream.java:242)
at java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
at java.base/java.util.zip.GZIPInputStream.read(GZIPInputStream.java:117)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:244)
at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:284)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:343)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._loadMore(UTF8StreamJsonParser.java:258)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._loadMoreGuaranteed(UTF8StreamJsonParser.java:2497)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString2(UTF8StreamJsonParser.java:2580)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishAndReturnString(UTF8StreamJsonParser.java:2560)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.getText(UTF8StreamJsonParser.java:335)
at com.google.api.client.json.jackson2.JacksonParser.getText(JacksonParser.java:74)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:856)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:451)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:787)
at com.google.api.client.json.JsonParser.parseArray(JsonParser.java:641)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:744)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:451)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:787)
at com.google.api.client.json.JsonParser.parseArray(JsonParser.java:641)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:744)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:451)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:787)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:360)
... 40 more
Suppressed: java.net.SocketException: Broken pipe
at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:425)
at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:445)
at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:831)
at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1045)
at java.base/sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:414)
... 80 more
Caused by: java.net.SocketException: Connection reset
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:328)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:355)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:808)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:976)
at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:484)
at java.base/sun.security.ssl.SSLSocketInputRecord.readHeader(SSLSocketInputRecord.java:478)
at java.base/sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:70)
at java.base/sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1465)
at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:1069)
... 76 mor
 

 

 

The error "BigQueryException: Connection has closed: javax.net.ssl.SSLException: Connection reset" usually indicates that the network connection to BigQuery was terminated unexpectedly. This can be caused by various network issues such as transient disruptions or restrictive network configurations like firewalls or proxies that terminate idle connections.

Here are some strategies to manage and potentially resolve this issue:

Implement a Retry Mechanism:

Use a retry mechanism with exponential backoff to handle connection resets gracefully. When a connection reset occurs, catch the exception, wait for a progressively increasing interval, and then retry the operation. This is especially useful for transient network issues.

Utilize Streaming for Large Result Sets:

Instead of attempting to load all results at once, process the results in smaller batches. Use the getQueryResults method with pagination tokens to handle large datasets efficiently. This reduces memory consumption and minimizes the impact of any single network disruption.

Adjust Network and Client Timeouts:

Increase the timeout settings in your BigQuery client configuration to allow longer periods for your operations to complete, particularly for queries that return large datasets or are known to take a long time.

Review Firewall and Proxy Configurations:

Ensure that any firewalls or proxy servers in your network path are configured to allow long-lived connections as required by your BigQuery operations. These systems might be closing connections that appear idle for too long.

Batch Processing with Pagination:

If persistent issues occur, consider breaking your query into smaller chunks. You can modify your query to retrieve subsets of the data and process each subset separately. This approach limits the impact of any single query failure.

Example (Handling Large Queries with Pagination and Retry):

 
String pageToken = null;
int retryCount = 0;
final int MAX_RETRIES = 5;

while (true) {
    try {
        TableResult tableResult = bigquery.getQueryResults(jobId, BigQuery.QueryResultsOption.pageToken(pageToken));
        for (FieldValueList row : tableResult.iterateAll()) {
            // Process each row here
        }
        pageToken = tableResult.getNextPageToken();
        if (pageToken == null) {
            break; // All pages have been processed
        }
        retryCount = 0; // Reset retry count after a successful batch
    } catch (BigQueryException e) {
        if (e.getCause() instanceof SSLException && e.getMessage().contains("Connection reset")) {
            if (retryCount < MAX_RETRIES) {
                retryCount++;
                int waitTime = 1000 * (int) Math.pow(2, retryCount); // Exponential backoff calculation
                System.err.println("Connection reset. Retrying after " + waitTime + " ms...");
                Thread.sleep(waitTime);
                continue; // Retry the operation
            } else {
                throw new RuntimeException("Maximum retries reached, unable to recover from SSLException", e);
            }
        } else {
            throw e; // Rethrow if it's not a recoverable SSLException
        }
    }
}

Hello @ms4446 ,
With the same code snippet earlier shared by @nachi_napo . We are facing one error like below
"Invalid read time 2024-12-04T18:55:52.913Z for table <query_results_table>. Cannot read before 2024-12-04T18:55:59.658Z".
We are doing a select <list_of_columns>  from <view_name>; and we have also defined a destination table <query_results_table> since the response is very large. The query runs for 7 days and errors out with above error.
Here number of columns is 50+ and over 500 million records.
We wanted to understand the error message.
What is exactly happening here? We are not reading/extracting anything directly from <query_results_table>. Does bigQuery internally uses Time Travel on the <query_results_table> ?
How can we fix this?

Thanks,
Satyam