spring-projects / spring-projects/spring-ai

org.springframework.web.client.RestClientException: Error while extracting response for type [org.springframework.ai.openai.api.OpenAiApi$ChatCompletion] and content type [application/json]

Open
#5,161 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage
Dominant language
Java
Stars
9.5k
Forks
2.9k
Avg merge
1d 7h
Merged PRs (30d)
6

Description

Bug description
When invoking a large model, the model requires a longer time for thinking, which leads to the disconnection of the network at the 60-second mark

Environment
spring-ai-bom 1.1.2
jdk17

Steps to reproduce
List list = deepSeekChatClient.prompt("获取小红书首页推送的笔记列表,获取前15条笔记的标题、封面图片地址、笔记详情地址")
.toolCallbacks(noteListTool)
.call()
.entity(new ParameterizedTypeReference<List>() {
});

After invoking the large model and then calling internal tools, the large model will think and output in a structured manner. The last step, where the model takes a long time to think, will result in an exception. Multiple tests have found that an exception occurs immediately if it takes more than 60 seconds
I have tried various configurations for underlying network requests, but none of them could solve the problem of reporting an error every 60 seconds
Expected behavior
I have tried various configurations for underlying network requests, but none of them could solve the problem of reporting an error every 60 seconds

Minimal Complete Reproducible example

2025-12-30T10:51:11.697+08:00 DEBUG 181680 --- [ient-1-Worker-3] .m.c.t.HttpClientStreamableHttpTransport : SendMessage finally: onComplete
2025-12-30T10:51:11.697+08:00 DEBUG 181680 --- [onPool-worker-1] .m.c.t.HttpClientStreamableHttpTransport : SSE connection established successfully
2025-12-30T10:52:11.865+08:00 WARN 181680 --- [ scheduling-1] o.springframework.ai.retry.RetryUtils : Retry error. Retry count:1

org.springframework.web.client.RestClientException: Error while extracting response for type [org.springframework.ai.openai.api.OpenAiApi$ChatCompletion] and content type [application/json]
at org.springframework.web.client.DefaultRestClient.readWithMessageConverters(DefaultRestClient.java:262) ~[spring-web-6.2.14.jar:6.2.14]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.readBody(DefaultRestClient.java:826) ~[spring-web-6.2.14.jar:6.2.14]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.lambda$toEntityInternal$2(DefaultRestClient.java:782) ~[spring-web-6.2.14.jar:6.2.14]
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:586) ~[spring-web-6.2.14.jar:6.2.14]
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchange(DefaultRestClient.java:540) ~[spring-web-6.2.14.jar:6.2.14]
at org.springframework.web.client.RestClient$RequestHeadersSpec.exchange(RestClient.java:680) ~[spring-web-6.2.14.jar:6.2.14]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.executeAndExtract(DefaultRestClient.java:821) ~[spring-web-6.2.14.jar:6.2.14]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.toEntityInternal(DefaultRestClient.java:781) ~[spring-web-6.2.14.jar:6.2.14]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.toEntity(DefaultRestClient.java:770) ~[spring-web-6.2.14.jar:6.2.14]
at org.springframework.ai.openai.api.OpenAiApi.chatCompletionEntity(OpenAiApi.java:214) ~[spring-ai-openai-1.1.2.jar:1.1.2]
at org.springframework.ai.openai.OpenAiChatModel.lambda$internalCall$1(OpenAiChatModel.java:200) ~[spring-ai-openai-1.1.2.jar:1.1.2]
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:357) ~[spring-retry-2.0.12.jar:na]
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:230) ~[spring-retry-2.0.12.jar:na]
at org.springframework.ai.openai.OpenAiChatModel.lambda$internalCall$3(OpenAiChatModel.java:200) ~[spring-ai-openai-1.1.2.jar:1.1.2]
at io.micrometer.observation.Observation.observe(Observation.java:564) ~[micrometer-observation-1.15.6.jar:1.15.6]
at org.springframework.ai.openai.OpenAiChatModel.internalCall(OpenAiChatModel.java:197) ~[spring-ai-openai-1.1.2.jar:1.1.2]
at org.springframework.ai.openai.OpenAiChatModel.internalCall(OpenAiChatModel.java:255) ~[spring-ai-openai-1.1.2.jar:1.1.2]
at org.springframework.ai.openai.OpenAiChatModel.call(OpenAiChatModel.java:182) ~[spring-ai-openai-1.1.2.jar:1.1.2]
at org.springframework.ai.chat.client.advisor.ChatModelCallAdvisor.adviseCall(ChatModelCallAdvisor.java:56) ~[spring-ai-client-chat-1.1.2.jar:1.1.2]
at org.springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.lambda$nextCall$1(DefaultAroundAdvisorChain.java:114) ~[spring-ai-client-chat-1.1.2.jar:1.1.2]
at io.micrometer.observation.Observation.observe(Observation.java:564) ~[micrometer-observation-1.15.6.jar:1.15.6]
at org.springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.nextCall(DefaultAroundAdvisorChain.java:113) ~[spring-ai-client-chat-1.1.2.jar:1.1.2]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.lambda$doGetObservableChatClientResponse$1(DefaultChatClient.java:539) ~[spring-ai-client-chat-1.1.2.jar:1.1.2]
at io.micrometer.observation.Observation.observe(Observation.java:564) ~[micrometer-observation-1.15.6.jar:1.15.6]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetObservableChatClientResponse(DefaultChatClient.java:537) ~[spring-ai-client-chat-1.1.2.jar:1.1.2]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doSingleWithBeanOutputConverter(DefaultChatClient.java:494) ~[spring-ai-client-chat-1.1.2.jar:1.1.2]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.entity(DefaultChatClient.java:458) ~[spring-ai-client-chat-1.1.2.jar:1.1.2]
at com.pa.infogatherserver.xihongshu.bussines.service.AbstractContentAuditService.collectNotes(AbstractContentAuditService.java:146) ~[classes/:na]
at com.pa.infogatherserver.xihongshu.bussines.service.AbstractContentAuditService.executeAudit(AbstractContentAuditService.java:81) ~[classes/:na]
at com.pa.infogatherserver.xihongshu.bussines.service.impl.XhsNoteInfoServiceImpl.getRecommendedNoteList(XhsNoteInfoServiceImpl.java:81) ~[classes/:na]
at com.pa.infogatherserver.xihongshu.bussines.service.impl.XhsNoteInfoServiceImpl.startGather(XhsNoteInfoServiceImpl.java:66) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360) ~[spring-aop-6.2.14.jar:6.2.14]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:724) ~[spring-aop-6.2.14.jar:6.2.14]
at com.pa.infogatherserver.xihongshu.bussines.service.impl.XhsNoteInfoServiceImpl$$SpringCGLIB$$0.startGather() ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[na:na]
at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) ~[spring-context-6.2.14.jar:6.2.14]
at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) ~[spring-context-6.2.14.jar:6.2.14]
at io.micrometer.observation.Observation.observe(Observation.java:498) ~[micrometer-observation-1.15.6.jar:1.15.6]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) ~[spring-context-6.2.14.jar:6.2.14]
at org.springframework.scheduling.config.Task$OutcomeTrackingRunnable.run(Task.java:87) ~[spring-context-6.2.14.jar:6.2.14]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-6.2.14.jar:6.2.14]
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:96) ~[spring-context-6.2.14.jar:6.2.14]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[na:na]
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264) ~[na:na]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java) ~[na:na]
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
Caused by: java.io.IOException: Premature EOF
at java.base/sun.net.www.http.ChunkedInputStream.readAheadBlocking(ChunkedInputStream.java:567) ~[na:na]
at java.base/sun.net.www.http.ChunkedInputStream.readAhead(ChunkedInputStream.java:611) ~[na:na]
at java.base/sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:705) ~[na:na]
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:132) ~[na:na]
at java.base/sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3735) ~[na:na]
at java.base/sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3728) ~[na:na]
at java.base/sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3716) ~[na:na]
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:82) ~[na:na]
at java.base/java.io.PushbackInputStream.read(PushbackInputStream.java:135) ~[na:na]
at org.springframework.web.client.IntrospectingClientHttpResponse.hasEmptyMessageBody(IntrospectingClientHttpResponse.java:103) ~[spring-web-6.2.14.jar:6.2.14]
at org.springframework.web.client.DefaultRestClient.readWithMessageConverters(DefaultRestClient.java:219) ~[spring-web-6.2.14.jar:6.2.14]
... 55 common frames omitted

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at OpenAiApi.chatCompletionEntity and OpenAiChatModel.internalCall, then inspect the reported DefaultRestClient stack and reproduce the 60-second failure with the provided tool-calling example. Trace why the response ends with Premature EOF and establish behavior that allows the long-running request to complete without the reported exception.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
ai, api, backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.