Please do a quick search on GitHub issues first, there might be already a duplicate issue for the one you are about to create. If the bug is trivial, just go ahead and create the issue. Otherwise, please take a few moments and fill in the following sections:

Bug description Spring AI calls VLLM to start the model with an error message

Environment spring ai 1.0.0-M8 JDK17 Steps to reproduce docker run --runtime nvidia --gpus all -p 8000:8000 --env "HF_HUB_OFFLINE=1" --ipc=host \ -v "/root/Qwen3-32B-AWQ:/models/Qwen3-32B-AWQ" \ --name=Qwen3-32B-AWQ vllm/vllm-openai:latest \ --model /models/Qwen3-32B-AWQ \ --tokenizer /models/Qwen3-32B-AWQ \ --served-model-name Qwen3-32B-AWQ \ --max-model-len 4096 \ --gpu-memory-utilization 0.9 \ --swap-space 32 \ --max-num-seqs 8 \ --enable-auto-tool-choice \ --tool-call-parser hermes \ --uvicorn-log-level trace

Expected behavior Spring AI calls VLLM to start the model with an error, but API POST calls the interface without an error

Minimal Complete Reproducible example 2025-05-13T09:44:42.702+08:00 DEBUG 12808 --- [tianli-spring-ai] [oundedElastic-3] o.s.a.c.c.advisor.SimpleLoggerAdvisor : request: AdvisedRequest[chatModel=OpenAiChatModel [defaultOptions=OpenAiChatOptions: {"streamUsage":false,"model":"Qwen3-32B-AWQ","temperature":0.7}], userText=你好, systemText=你是一个热心、可爱的只能助手。你是名字是甜梨小助手,请用中文回答用户的问题。语气保持开心,并根据用户内容告诉接下来的提示词可以问什么。, chatOptions=OpenAiChatOptions: {"streamUsage":false,"model":"Qwen3-32B-AWQ","temperature":0.7}, media=[], toolNames=[], toolCallbacks=[], messages=[], userParams={}, systemParams={}, advisors=[SimpleLoggerAdvisor, org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor@21d9a812, org.springframework.ai.chat.client.advisor.ChatModelCallAdvisor@36842c9c, org.springframework.ai.chat.client.advisor.ChatModelStreamAdvisor@3843c43c], advisorParams={}, adviseContext={spring.ai.chat.client.model=OpenAiChatModel [defaultOptions=OpenAiChatOptions: {"streamUsage":false,"model":"Qwen3-32B-AWQ","temperature":0.7}], chat_memory_conversation_id=1747100680497, spring.ai.chat.client.advisors=[SimpleLoggerAdvisor, org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor@21d9a812, org.springframework.ai.chat.client.advisor.ChatModelCallAdvisor@36842c9c, org.springframework.ai.chat.client.advisor.ChatModelStreamAdvisor@3843c43c], spring.ai.chat.client.user.params={}, spring.ai.chat.client.system.params={}}, toolContext={}] 2025-05-13T09:44:42.705+08:00 TRACE 12808 --- [tianli-spring-ai] [oundedElastic-3] o.s.w.r.f.client.ExchangeFunctions : [3c7c47ec] HTTP POST http://192.168.31.35:8000/v1/chat/completions, headers={masked} 2025-05-13T09:44:42.781+08:00 TRACE 12808 --- [tianli-spring-ai] [onPool-worker-2] o.s.w.r.f.client.ExchangeFunctions : [3c7c47ec] [7235b1de] Response 400 BAD_REQUEST, headers={masked} 2025-05-13T09:44:42.784+08:00 ERROR 12808 --- [tianli-spring-ai] [onPool-worker-2] o.s.ai.chat.model.MessageAggregator : Aggregation Error

org.springframework.web.reactive.function.client.WebClientResponseException$BadRequest: 400 Bad Request from POST http://192.168.31.35:8000/v1/chat/completions at org.springframework.web.reactive.function.client.WebClientResponseException.create(WebClientResponseException.java:321) ~[spring-webflux-6.2.5.jar:6.2.5] Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: Error has been observed at the following site(s): *__checkpoint ⇢ 400 BAD_REQUEST from POST http://192.168.31.35:8000/v1/chat/completions [DefaultWebClient] Original Stack Trace: at org.springframework.web.reactive.function.client.WebClientResponseException.create(WebClientResponseException.java:321) ~[spring-webflux-6.2.5.jar:6.2.5] at org.springframework.web.reactive.function.client.DefaultClientResponse.lambda$createException$1(DefaultClientResponse.java:214) ~[spring-webflux-6.2.5.jar:6.2.5] at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:106) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxOnErrorReturn$ReturnSubscriber.onNext(FluxOnErrorReturn.java:162) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onNext(FluxDefaultIfEmpty.java:122) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:299) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:337) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.Operators$BaseFluxToMonoOperator.completePossiblyEmpty(Operators.java:2097) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.MonoCollect$CollectSubscriber.onComplete(MonoCollect.java:145) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxPublish$PublishSubscriber.checkTerminated(FluxPublish.java:634) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxPublish$PublishSubscriber.drain(FluxPublish.java:494) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxPublish$PublishSubscriber.onComplete(FluxPublish.java:355) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onComplete(FluxContextWrite.java:126) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onComplete(FluxMapFuseable.java:350) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxFlattenIterable$FlattenIterableSubscriber.drainAsync(FluxFlattenIterable.java:371) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxFlattenIterable$FlattenIterableSubscriber.drain(FluxFlattenIterable.java:724) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxFlattenIterable$FlattenIterableSubscriber.onComplete(FluxFlattenIterable.java:273) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.adapter.JdkFlowAdapter$SubscriberToRS.onComplete(JdkFlowAdapter.java:160) ~[reactor-core-3.7.4.jar:3.7.4] at java.net.http/jdk.internal.net.http.ResponseSubscribers$PublishingBodySubscriber.complete(ResponseSubscribers.java:933) ~[java.net.http:na] at java.net.http/jdk.internal.net.http.ResponseSubscribers$PublishingBodySubscriber.lambda$new$1(ResponseSubscribers.java:864) ~[java.net.http:na] at java.base/java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:718) ~[na:na] at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[na:na] at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147) ~[na:na] at java.net.http/jdk.internal.net.http.ResponseSubscribers$PublishingBodySubscriber.lambda$subscribe$3(ResponseSubscribers.java:961) ~[java.net.http:na] at java.base/java.util.concurrent.CompletableFuture.uniAcceptNow(CompletableFuture.java:757) ~[na:na] at java.base/java.util.concurrent.CompletableFuture.uniAcceptStage(CompletableFuture.java:735) ~[na:na] at java.base/java.util.concurrent.CompletableFuture.thenAccept(CompletableFuture.java:2182) ~[na:na] at java.net.http/jdk.internal.net.http.ResponseSubscribers$PublishingBodySubscriber.subscribe(ResponseSubscribers.java:957) ~[java.net.http:na] at reactor.adapter.JdkFlowAdapter$FlowPublisherAsFlux.subscribe(JdkFlowAdapter.java:68) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.InternalFluxOperator.subscribe(InternalFluxOperator.java:68) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxPublish.connect(FluxPublish.java:106) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxAutoConnect.subscribe(FluxAutoConnect.java:62) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.Flux.subscribe(Flux.java:8891) ~[reactor-core-3.7.4.jar:3.7.4] at org.springframework.http.client.reactive.AbstractClientHttpResponse$SingleSubscriberPublisher.subscribe(AbstractClientHttpResponse.java:112) ~[spring-web-6.2.5.jar:6.2.5] at reactor.core.publisher.FluxSource.subscribe(FluxSource.java:71) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.Flux.subscribe(Flux.java:8891) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onNext(MonoFlatMapMany.java:196) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onNext(FluxDoFinally.java:113) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:180) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onNext(FluxPeekFuseable.java:854) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.complete(MonoIgnoreThen.java:294) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onNext(MonoIgnoreThen.java:188) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.MonoCompletionStage$MonoCompletionStageSubscription.apply(MonoCompletionStage.java:121) ~[reactor-core-3.7.4.jar:3.7.4] at reactor.core.publisher.MonoCompletionStage$MonoCompletionStageSubscription.apply(MonoCompletionStage.java:67) ~[reactor-core-3.7.4.jar:3.7.4] at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934) ~[na:na] at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911) ~[na:na] at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[na:na] at java.base/java.util.concurrent.CompletableFuture.postFire(CompletableFuture.java:614) ~[na:na] at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:844) ~[na:na] at java.base/java.util.concurrent.CompletableFuture$Completion.exec(CompletableFuture.java:483) ~[na:na] at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373) ~[na:na] at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182) ~[na:na] at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655) ~[na:na] at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622) ~[na:na] at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165) ~[na:na]

2025-05-13T09:44:42.786+08:00 ERROR 12808 --- [tianli-spring-ai] [oundedElastic-4] o.s.ai.chat.model.MessageAggregator : Aggregation Error

Image

Image

Image

Comment From: lanyuanxiaoyao

Just force the http client use http1.1

import java.net.http.HttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.client.JdkClientHttpRequestFactory;
import org.springframework.http.client.reactive.JdkClientHttpConnector;
import org.springframework.web.client.RestClient;
import org.springframework.web.reactive.function.client.WebClient;

@Configuration
public class HttpClientConfiguration {
  private HttpClient client() {
    return HttpClient.newBuilder()
        .version(HttpClient.Version.HTTP_1_1)
        .build();
  }

  @Bean
  @Primary
  public RestClient.Builder restClientBuilder() {
    return RestClient.builder()
        .requestFactory(new JdkClientHttpRequestFactory(client()));
  }

  @Bean
  @Primary
  public WebClient.Builder webClientBuilder() {
    return WebClient.builder()
        .clientConnector(new JdkClientHttpConnector(client()));
  }
}

Comment From: tianli-sir

Just force the http client use http1.1

``` import java.net.http.HttpClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.http.client.JdkClientHttpRequestFactory; import org.springframework.http.client.reactive.JdkClientHttpConnector; import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.WebClient;

@Configuration public class HttpClientConfiguration { private HttpClient client() { return HttpClient.newBuilder() .version(HttpClient.Version.HTTP_1_1) .build(); }

@Bean @Primary public RestClient.Builder restClientBuilder() { return RestClient.builder() .requestFactory(new JdkClientHttpRequestFactory(client())); }

@Bean @Primary public WebClient.Builder webClientBuilder() { return WebClient.builder() .clientConnector(new JdkClientHttpConnector(client())); } } ```

感谢大佬,解决了,现在调用工具时出现了新得问题,和这个一样https://github.com/spring-projects/spring-ai/issues/3280

Comment From: wenyuanLv

3280 你解决了吗大佬,我发现调用没有参数的工具的时候,就会出现这个问题

Comment From: wenyuanLv

@tianli-sir 你解决了吗大佬,我发现调用没有参数的工具的时候,就会出现这个问题

Comment From: tianli-sir

@tianli-sir 你解决了吗大佬,我发现调用没有参数的工具的时候,就会出现这个问题

随便加个参数就可以啦