-
Notifications
You must be signed in to change notification settings - Fork 9.2k
Description
OkHttp version 4.12.0
Description
When retryOnConnectionFailure is enabled (default behavior), OkHttp retries failed requests (e.g., due to connection errors) by reusing the same RequestBody. For multipart uploads using a non-repeatable InputStream (e.g., ByteArrayInputStream), the stream is fully consumed during the first attempt. This results in an empty payload (0-byte file) being sent on retry, leading to data loss or incomplete uploads.
This issue affects scenarios like file uploads where the InputStream cannot be reliably reset (e.g., network streams). Workarounds include disabling retries (retryOnConnectionFailure(false)) but they are not ideal when relying on automatic retries.
A common attempt to fix this is calling InputStream.reset() after marking the stream, but this fails because OkHttp's retry mechanism does not provide a hook to reset the stream between attempts.
Steps to Reproduce
- Create an OkHttp client with
retryOnConnectionFailure(true)(default). - Prepare a multipart
RequestBodyusing a non-repeatableInputStream(e.g.,ByteArrayInputStream). - Send a POST request to a mock server (e.g., via WireMock) that simulates a connection failure on the first attempt (e.g., returns an empty response or fault to trigger retry).
- Observe the retry request: The
InputStreamis exhausted, sending an empty body (0 bytes).