Reputation: 17507
I got this exception occasionally when try to upload files (image, audio) to S3. Is there any solution for this?
Configuration: Android 4x, 5x, aws-android-sdk-s3 version 2.2.14.
Unable to execute HTTP request: Write error: ssl=0x9ab52680: I/O error during system call, Connection reset by peer
javax.net.ssl.SSLException: Write error: ssl=0x9ab52680: I/O error during system call, Connection reset by peer
at com.android.org.conscrypt.NativeCrypto.SSL_write(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:766)
at com.android.okhttp.okio.Okio$1.write(Okio.java:76)
at com.android.okhttp.okio.AsyncTimeout$1.write(AsyncTimeout.java:155)
at com.android.okhttp.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:176)
at com.android.okhttp.okio.RealBufferedSink.write(RealBufferedSink.java:46)
at com.android.okhttp.internal.http.HttpConnection$FixedLengthSink.write(HttpConnection.java:302)
at com.android.okhttp.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:176)
at com.android.okhttp.okio.RealBufferedSink$1.write(RealBufferedSink.java:198)
at com.amazonaws.http.UrlHttpClient.write(UrlHttpClient.java:172)
at com.amazonaws.http.UrlHttpClient.writeContentToConnection(UrlHttpClient.java:129)
at com.amazonaws.http.UrlHttpClient.execute(UrlHttpClient.java:65)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:360)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:199)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4221)
at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1628)
at net.tandem.ext.aws.AmazonUtil.uploadFile(AmazonUtil.java:131)
at net.tandem.ext.aws.AmazonUtil.uploadFile(AmazonUtil.java:65)
at net.tandem.service.MessageService$2.doInBackground(MessageService.java:323)
at net.tandem.service.MessageService$2.doInBackground(MessageService.java:315)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Upvotes: 7
Views: 17444
Reputation: 850
Also important to note regarding the very unforgiving upload API of S3 - if you use POST
instead of PUT
you will get this horrible SSL error, when you should be getting 405 Method not allowed
which will clearly explain what went wrong.
Bottom line: make sure you use PUT
when uploading to S3
Upvotes: 2
Reputation: 3373
I have just hit this issue, but it fails always with the Connection reset by peer
. I am not using the AWS SDK, but OkHttp directly (v 3.9.1).
The problem in my case was solved when I replaced OkHttp with Java's HttpURLConnection
. My Android Kotlin code is inspired by AWS's documentation example:
private fun uploadFileRaw(file: Uri, uploadUrl: String, contentResolver: ContentResolver) : Int {
val url = URL(uploadUrl)
val connection = url.openConnection() as HttpURLConnection
connection.doOutput = true
connection.requestMethod = "PUT"
val out = connection.outputStream
contentResolver.openInputStream(file).use {
it.copyTo(out)
}
out.close()
return connection.responseCode
}
Upvotes: 0
Reputation: 2991
I was having the same error but it was due to time difference between the Android devices and the server (time skew).
When I started messing around with the time and timezone of the device I found a pattern to reproduce this same error (it was not random, with a certain date and timezone on the device the upload/download always failed).
If this is your case, the fix is to use the s3client.setTimeOffset() to correct the time skew between the devices and the s3 server.
Edit:
This is how I changed the time skew on the device code:
amazonS3Client.setTimeOffset(getTimeSkew());
...
private int getTimeSkew() {
long dif = (new Date()).getTime() - TimeHelper.getUTCTimeInMillis();
return (int)(dif/(long)1000);
}
In the method getUTCTimeInMillis()
I get the time from an external server that I know it returns current time in UTC.
Hope it helps.
Upvotes: 3
Reputation: 179114
The solution is to retry the request.
Connection reset by peer theoretically means the far end server reset the connection, due to a fault in the communication or an internal error, though in practice, intermediate equipment (particularly firewalls and NAT/PAT devices) can also craft a response packet that generates this same error.
Usually this though be interpreted as a consequence of traffic traversing the Internet -- sometimes things go wrong, outside your control.
This condition should only indicate you're doing something wrong (something you can correct) if the same request repeatedly throws an error while other requests are succeeding.
Upvotes: 11