Skip to content

GH-6318: Recover from stale pooled connections in OpenAI OkHttp client#6323

Open
sdudzin wants to merge 1 commit into
spring-projects:mainfrom
sdudzin:GH-6318-retry-on-connection-failure
Open

GH-6318: Recover from stale pooled connections in OpenAI OkHttp client#6323
sdudzin wants to merge 1 commit into
spring-projects:mainfrom
sdudzin:GH-6318-retry-on-connection-failure

Conversation

@sdudzin
Copy link
Copy Markdown

@sdudzin sdudzin commented Jun 6, 2026

Fixes #6318.

When the OpenAI client talks to a server that closes idle keep-alive connections (e.g. llama.cpp), the next request reuses the dead connection and fails with EOFException: \n not found: limit=0 / unexpected end of stream.

The cause: SpringAiOpenAiHttpClient set retryOnConnectionFailure(false) to "avoid doubling" with the SDK's RetryingHttpClient. They are not the same thing — OkHttp's flag silently re-opens broken connections, the SDK retries HTTP status codes with backoff. They do not duplicate.

Fix: restore OkHttp's default (retryOnConnectionFailure(true)).

Tests: new SpringAiOpenAiHttpClientTests — one config guard plus one MockWebServer test that reproduces the recovery using SocketPolicy.DISCONNECT_AT_END. Verified to fail (with the exact issue symptom) if the flag is reverted.

…AI OkHttp client

Fixes spring-projectsGH-6318 (spring-projects#6318)

* re-enable OkHttp's retryOnConnectionFailure (the OkHttp default) in
  SpringAiOpenAiHttpClient. With it disabled, when a server like llama.cpp
  closes an idle keep-alive connection, the next request reuses that dead
  connection and fails with "unexpected end of stream" / EOFException
  instead of being silently retried on a fresh connection.
* the previous code disabled this flag thinking it would duplicate the
  OpenAI SDK's RetryingHttpClient. The two work at different layers:
  OkHttp's flag retries broken connections instantly with no backoff; the
  SDK's retries are based on HTTP status codes (408/429/5xx) and use
  exponential backoff. They do not overlap, so there is no duplication.
* add SpringAiOpenAiHttpClientTests: a configuration guard plus a
  MockWebServer test that reproduces the EOFException recovery using
  SocketPolicy.DISCONNECT_AT_END (a stale pooled connection).

Signed-off-by: Siarhei Dudzin <606713+sdudzin@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

disabling retryOnConnectionFailure causes java.io.EOFException: \n not found: limit=0 content=…

1 participant