Potential data corruption issue for OCI Java SDK on binary data upload with default retries
Update 2022-06-07: We have fixed this issue in version 2.31.0. If you are using any of the OCI Java SDK synchronous clients that upload streams of data and you do not define the RetryConfiguration at client level or request level, we urge you to update to version 2.31.0.
If you are using any of the OCI Java SDK synchronous clients that upload streams of data, e.g. ObjectStorageClient or DataSafeClient, and you do not define the RetryConfiguration at client level or request level, you may be affected by silent data corruption.
Description
When using OCI Java SDK (versions >= 2.10.0) for operations that have retries enabled by default, and you do not define the RetryConfiguration at client level or request level, and the request fails with a retry-able error, the OCI Java SDK will automatically retry the request. In this situation, the clients fail to reset the stream position for requests that upload streams. As a result, an empty stream (or a stream starting in the middle) is successfully uploaded, and success may be returned, even though the actual entire stream content was not uploaded.
Affected operations with versions
This happens only for synchronous clients in certain versions :
- Affected operation :
ObjectStorageClient.putObject- link to method Affected versions :>= 2.14.0 - Affected operation :
ObjectStorageClient.uploadPart- link to method Affected versions :>= 2.14.0 - Affected operation :
DataSafeClient.uploadMaskingPolicy- link to method Affected versions :>= 2.25.0 - Affected operation :
DataSafeClient.uploadSensitiveDataModel- link to method Affected versions :>= 2.25.0 - Affected operation :
DataScienceClient.createModelArtifact- link to method Affected versions :>= 2.26.0
Operations that do not upload streams are not affected.
If the contentLength is set in PutObjectRequest or UploadPartRequest, uploads using ObjectStorageClient.putObject are not affected.
To summarize, you are affected if you
- upload streams using the above operations,
- and do not set a retry configuration at client level or request level
- and do not set the
contentLength
Workarounds
Fixing this issue is our highest priority, and we are actively working on it. In the meantime, here are some possible workarounds:
- Set the
RetryConfigurationat client level or request level by following this example - Disable default retries by following any of the methods described here
- Set the
contentLength, if the operation supports it (e.g.ObjectStorageClient.putObject). If the client fails to write the exact number of bytes, the operation will fail and data corruption can be avoided. - Set the
contentMD5, if you can compute it and the operation supports it (e.g.ObjectStorageClient.putObject). Then compare the MD5 hash returned in the response to your pre-computed MD5 hash.