This repository was archived by the owner on Sep 25, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Sep 25, 2026. It is now read-only.
Can not download ~200GB file using storage blob #1425
Copy link
Copy link
Closed
Labels
api: storageIssues related to the googleapis/java-storage API.Issues related to the googleapis/java-storage API.priority: p2Moderately-important priority. Fix may not be included in next release.Moderately-important priority. Fix may not be included in next release.status: investigatingThe issue is under investigation, which is determined to be non-trivial.The issue is under investigation, which is determined to be non-trivial.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Description
Execution fails when ~128gb is downloaded and code fail does not depend on time spent on downloading this 128 gb of file.
Environment details
OS type and version: Linux
Java version: 11
Code example
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty(GoogleCredentialsConstants.CLIENT_ID, CLIENT_ID);
jsonObject.addProperty(GoogleCredentialsConstants.CLIENT_EMAIL, CLIENT_EMAIL);
jsonObject.addProperty(GoogleCredentialsConstants.ACCOUNT_TYPE, ACCOUNT_TYPE);
jsonObject.addProperty(GoogleCredentialsConstants.PRIVATE_KEY_ID, PRIVATE_KEY_ID);
jsonObject.addProperty(GoogleCredentialsConstants.PRIVATE_KEY, PRIVATE_KEY);
String credentials = jsonObject.toString();
GoogleCredentials googleCredentials;
try (InputStream inputStream = new ByteArrayInputStream(credentials.getBytes(StandardCharsets.UTF_8))) {
googleCredentials = GoogleCredentials.fromStream(inputStream);
} catch (IOException ex) {
throw new CustomException(ex);
}
Storage storage = StorageOptions.newBuilder()
.setProjectId(projectId)
.setCredentials(googleCredentials )
.build()
.getService();
Blob blob = storage.get(BlobId.of(bucketName, remoteFilePath));
blob.downloadTo(localFilePath); // line where code failsStack trace
Caused by: java.net.SocketException: Connection reset by peer (Write failed)
at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
at java.base/java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.base/java.net.SocketOutputStream.write(Unknown Source)
at java.base/sun.security.ssl.SSLSocketOutputRecord.flush(Unknown Source)
at java.base/sun.security.ssl.OutputRecord.changeWriteCiphers(Unknown Source)
at java.base/sun.security.ssl.KeyUpdate$KeyUpdateProducer.produce(Unknown Source)
at java.base/sun.security.ssl.KeyUpdate$KeyUpdateKickstartProducer.produce(Unknown Source)
at java.base/sun.security.ssl.SSLHandshake.kickstart(Unknown Source)
at java.base/sun.security.ssl.PostHandshakeContext.kickstart(Unknown Source)
at java.base/sun.security.ssl.TransportContext.kickstart(Unknown Source)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at java.base/sun.security.ssl.SSLSocketImpl.tryKeyUpdate(Unknown Source)
at java.base/sun.security.ssl.SSLSocketImpl.decode(Unknown Source)
at java.base/sun.security.ssl.SSLSocketImpl.readApplicationRecord(Unknown Source)
at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(Unknown Source)
at java.base/java.io.BufferedInputStream.read1(Unknown Source)
at java.base/java.io.BufferedInputStream.read(Unknown Source)
at java.base/sun.net.www.MeteredStream.read(Unknown Source)
at java.base/java.io.FilterInputStream.read(Unknown Source)
at java.base/sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
at com.google.api.client.http.javanet.NetHttpResponse$SizeValidatingInputStream.read(NetHttpResponse.java:164)
at java.base/java.io.BufferedInputStream.read1(Unknown Source)
at java.base/java.io.BufferedInputStream.read(Unknown Source)
at java.base/java.io.FilterInputStream.read(Unknown Source)
at com.google.common.io.ByteStreams.copy(ByteStreams.java:112)
at com.google.api.client.googleapis.media.MediaHttpDownloader.executeCurrentRequest(MediaHttpDownloader.java:243)
at com.google.api.client.googleapis.media.MediaHttpDownloader.download(MediaHttpDownloader.java:183)
at com.google.api.client.googleapis.media.MediaHttpDownloader.download(MediaHttpDownloader.java:142)
Metadata
Metadata
Assignees
Labels
api: storageIssues related to the googleapis/java-storage API.Issues related to the googleapis/java-storage API.priority: p2Moderately-important priority. Fix may not be included in next release.Moderately-important priority. Fix may not be included in next release.status: investigatingThe issue is under investigation, which is determined to be non-trivial.The issue is under investigation, which is determined to be non-trivial.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Activity
BenWhitehead commentedon May 31, 2022
Hi @rdubitsky-syberry,
What version of
com.google.cloud:google-cloud-storageare you using (mvn dependency:list -Dincludes=com.google.cloud:google-cloud-storage)?Additionally, what type/size of instance are you trying to download the blob to?
rdubitsky-syberry commentedon May 31, 2022
Hi @BenWhitehead
com.google.cloud:google-cloud-storage:2.4.0 is used
Type of instance is csv, size is 220 GB.
BenWhitehead commentedon May 31, 2022
Hi @rdubitsky-syberry,
Thanks for confirming. I'll see what I can determine for a fix.
In the meantime, if you're blocked on this an alternative approach that could be used is as follows:
This method will be slower than
downloadTobut has the advantage that it can incrementally retry the download.rdubitsky-syberry commentedon Jun 1, 2022
Hi, @BenWhitehead
Thanks for alternative approach. I have already used it, but the reason I use
downloadTois that it is quicker thancopy. Hope you'll come up with some fix.Thanks in advance.
BenWhitehead commentedon Jun 3, 2022
Wanted to let you know, I have been able to get the error to happen with some reliability (~60%). I'm still trying to figure out why it's erroring and not retrying from where it left off. The implementation of downloadTo should be attempting to retry the request.
fix: update request method of HttpStorageRpc to properly configure of…
fix: update request method of HttpStorageRpc to properly configure of…
fix: update request method of HttpStorageRpc to properly configure of…
fix: update request method of HttpStorageRpc to properly configure of…
fix: update request method of HttpStorageRpc to properly configure of…
fix: update request method of HttpStorageRpc to properly configure of…
denis-yusevich commentedon Jul 29, 2022
Hello @BenWhitehead! We are using google-cloud-storage:2.9.2 now, which contains your fixes, but still facing the same problem:
after downloading about 50% of the file, socket hangs up and the same error arises. Please, take a look at it.
Thanks in advance!
BenWhitehead commentedon Aug 9, 2022
I spent some more time trying to diagnose why it may still be happening for you, but unfortunately haven't been able to narrow down exactly what's happening.
My best guess, but still unverified (the code is pretty difficult to trace precisely for order of operations), that that somehow the retry budget is exhausted to such a point that when the retry tries to determine if it can retry there isn't any budget left. If I'm able to prove one way or the other I'll report back.
denis-yusevich commentedon Sep 23, 2022
Hi @BenWhitehead! Do you have any updates on this issue? Please let me now if there is some progress
BenWhitehead commentedon Sep 23, 2022
Apologies for the long delay, lots of things got in the way.
From what I've been able to suss out, this behavior seems to be related to the
totalTimeoutvalue from the RetrySettings. When a call fails, in addition to checking whether the error is retriable the elapsed time will be checked against thetotalTimeout. If the previous invocation(s) elapsed time exceeds thetotalTimeoutthen the Retryer will not proceed.The reason we don't see the error when using the ReadChannel is that currently the ReadChannel issues a new RPC for each chunk's worth of data, whereas downloadTo will open a single request and read from the socket as long as it can.
To allow retries to happen on such large files you'll need to increase the
totalTimeoutfor your instance of Storage similar to how it's demonstrated in the java code sample on https://cloud.google.com/storage/docs/retry-strategy (How Cloud Storage tools implement retry strategies > Client libraries > Java).In case you're curious below is the minimized repro I was able to generate after digging about:
Minimized Reproduction of behavior
Code
Output
BenWhitehead commentedon Feb 1, 2023
Hi again, after the recent fix in #1799 the alternative approach in #1425 (comment) is now provides bandwidth competitive with downloadTo[1] and providing transparent automatic retries.
For the next major version we will very likely switch the internals of
downloadToto use the new reader to gain these benefits transparently.