Skip to content

Unstable MCP WebMVC server when MCP client connects #3035

Open
@jpomykala

Description

@jpomykala

Bug description

Minimal Spring Boot application with Spring AI WebMVC MCP Server produces a lot of errors and warnings when any MCP clients connects to it. MCP Clients also randomly disconnects and reconnects to the MCP Server.

2025-05-07T21:33:51.842+02:00 ERROR 64151 --- [io-8080-exec-10] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session a2c209b5-4f6a-4675-8c4c-39733c6b5823: null
2025-05-07T21:33:51.849+02:00  WARN 64151 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Ignoring exception, response committed already: org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class java.util.LinkedHashMap] with preset Content-Type 'text/event-stream'
2025-05-07T21:33:51.850+02:00  WARN 64151 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class java.util.LinkedHashMap] with preset Content-Type 'text/event-stream']
2025-05-07T21:33:54.037+02:00  INFO 64151 --- [nio-8080-exec-7] i.m.server.McpAsyncServer                : Client initialize request - Protocol: 2024-11-05, Capabilities: ClientCapabilities[experimental=null, roots=RootCapabilities[listChanged=false], sampling=null], Info: Implementation[name=cursor-vscode, version=1.0.0]
2025-05-07T21:33:54.037+02:00  INFO 64151 --- [nio-8080-exec-4] i.m.server.McpAsyncServer                : Client initialize request - Protocol: 2024-11-05, Capabilities: ClientCapabilities[experimental=null, roots=RootCapabilities[listChanged=false], sampling=null], Info: Implementation[name=cursor-vscode, version=1.0.0]
2025-05-07T21:33:54.037+02:00 ERROR 64151 --- [nio-8080-exec-7] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session a2c209b5-4f6a-4675-8c4c-39733c6b5823: Cannot invoke "org.apache.catalina.connector.OutputBuffer.isBlocking()" because "this.ob" is null
2025-05-07T21:33:54.037+02:00 ERROR 64151 --- [nio-8080-exec-4] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session a2c209b5-4f6a-4675-8c4c-39733c6b5823: Cannot invoke "org.apache.catalina.connector.OutputBuffer.isBlocking()" because "this.ob" is null
2025-05-07T21:33:54.038+02:00 ERROR 64151 --- [nio-8080-exec-4] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 1c57403f-180f-4079-a8ca-b9554aaf383a: null
2025-05-07T21:33:54.038+02:00 ERROR 64151 --- [nio-8080-exec-4] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 5c0cb168-06fb-4981-83f2-604789055d4a: ServletOutputStream failed to flush: java.io.IOException: Broken pipe
2025-05-07T21:33:54.039+02:00 ERROR 64151 --- [nio-8080-exec-4] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 5e0c7216-87ce-4dc6-a418-de8e4297f5a8: ServletOutputStream failed to flush: java.io.IOException: Broken pipe
2025-05-07T21:33:54.039+02:00 ERROR 64151 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] threw exception

java.nio.BufferOverflowException: null
	at java.base/java.nio.HeapByteBuffer.put(HeapByteBuffer.java:238) ~[na:na]
	at org.apache.catalina.connector.OutputBuffer.transfer(OutputBuffer.java:802) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:670) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:377) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:355) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:102) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.springframework.web.context.request.async.StandardServletAsyncWebRequest$LifecycleServletOutputStream.write(StandardServletAsyncWebRequest.java:401) ~[spring-web-6.2.6.jar:6.2.6]
	at java.base/java.io.OutputStream.write(OutputStream.java:124) ~[na:na]
	at org.springframework.web.servlet.function.SseServerResponse$DefaultSseBuilder.send(SseServerResponse.java:143) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at org.springframework.web.servlet.function.SseServerResponse$DefaultSseBuilder.writeString(SseServerResponse.java:205) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at org.springframework.web.servlet.function.SseServerResponse$DefaultSseBuilder.data(SseServerResponse.java:193) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at io.modelcontextprotocol.server.transport.WebMvcSseServerTransport.lambda$sendMessage$0(WebMvcSseServerTransport.java:181) ~[mcp-spring-webmvc-0.7.0.jar:0.7.0]
	at java.base/java.util.concurrent.ConcurrentHashMap$ValuesView.forEach(ConcurrentHashMap.java:4783) ~[na:na]
	at io.modelcontextprotocol.server.transport.WebMvcSseServerTransport.lambda$sendMessage$1(WebMvcSseServerTransport.java:179) ~[mcp-spring-webmvc-0.7.0.jar:0.7.0]
	at reactor.core.publisher.MonoRunnable.subscribe(MonoRunnable.java:49) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4576) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribeWith(Mono.java:4641) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4403) ~[reactor-core-3.7.5.jar:3.7.5]
	at io.modelcontextprotocol.spec.DefaultMcpSession.lambda$new$0(DefaultMcpSession.java:138) ~[mcp-0.7.0.jar:0.7.0]
	at reactor.core.publisher.LambdaMonoSubscriber.onNext(LambdaMonoSubscriber.java:171) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2570) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2366) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onSubscribe(FluxOnErrorResume.java:74) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:76) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4576) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribeWith(Mono.java:4641) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4542) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4478) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4450) ~[reactor-core-3.7.5.jar:3.7.5]
	at io.modelcontextprotocol.spec.DefaultMcpSession.lambda$new$3(DefaultMcpSession.java:138) ~[mcp-0.7.0.jar:0.7.0]
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:196) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2570) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.BlockingSingleSubscriber.onSubscribe(BlockingSingleSubscriber.java:54) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4576) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.block(Mono.java:1778) ~[reactor-core-3.7.5.jar:3.7.5]
	at io.modelcontextprotocol.server.transport.WebMvcSseServerTransport.handleMessage(WebMvcSseServerTransport.java:263) ~[mcp-spring-webmvc-0.7.0.jar:0.7.0]
	at org.springframework.web.servlet.function.support.HandlerFunctionAdapter.handle(HandlerFunctionAdapter.java:108) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) ~[tomcat-embed-core-10.1.40.jar:6.0]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.40.jar:6.0]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.2.6.jar:6.2.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.6.jar:6.2.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.2.6.jar:6.2.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.6.jar:6.2.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.2.6.jar:6.2.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.6.jar:6.2.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na]

2025-05-07T21:33:54.040+02:00 ERROR 64151 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.nio.BufferOverflowException] with root cause

java.nio.BufferOverflowException: null
	at java.base/java.nio.HeapByteBuffer.put(HeapByteBuffer.java:238) ~[na:na]
	at org.apache.catalina.connector.OutputBuffer.transfer(OutputBuffer.java:802) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:670) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:377) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:355) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:102) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.springframework.web.context.request.async.StandardServletAsyncWebRequest$LifecycleServletOutputStream.write(StandardServletAsyncWebRequest.java:401) ~[spring-web-6.2.6.jar:6.2.6]
	at java.base/java.io.OutputStream.write(OutputStream.java:124) ~[na:na]
	at org.springframework.web.servlet.function.SseServerResponse$DefaultSseBuilder.send(SseServerResponse.java:143) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at org.springframework.web.servlet.function.SseServerResponse$DefaultSseBuilder.writeString(SseServerResponse.java:205) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at org.springframework.web.servlet.function.SseServerResponse$DefaultSseBuilder.data(SseServerResponse.java:193) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at io.modelcontextprotocol.server.transport.WebMvcSseServerTransport.lambda$sendMessage$0(WebMvcSseServerTransport.java:181) ~[mcp-spring-webmvc-0.7.0.jar:0.7.0]
	at java.base/java.util.concurrent.ConcurrentHashMap$ValuesView.forEach(ConcurrentHashMap.java:4783) ~[na:na]
	at io.modelcontextprotocol.server.transport.WebMvcSseServerTransport.lambda$sendMessage$1(WebMvcSseServerTransport.java:179) ~[mcp-spring-webmvc-0.7.0.jar:0.7.0]
	at reactor.core.publisher.MonoRunnable.subscribe(MonoRunnable.java:49) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4576) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribeWith(Mono.java:4641) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4403) ~[reactor-core-3.7.5.jar:3.7.5]
	at io.modelcontextprotocol.spec.DefaultMcpSession.lambda$new$0(DefaultMcpSession.java:138) ~[mcp-0.7.0.jar:0.7.0]
	at reactor.core.publisher.LambdaMonoSubscriber.onNext(LambdaMonoSubscriber.java:171) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2570) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2366) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onSubscribe(FluxOnErrorResume.java:74) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:76) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4576) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribeWith(Mono.java:4641) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4542) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4478) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4450) ~[reactor-core-3.7.5.jar:3.7.5]
	at io.modelcontextprotocol.spec.DefaultMcpSession.lambda$new$3(DefaultMcpSession.java:138) ~[mcp-0.7.0.jar:0.7.0]
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:196) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2570) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.BlockingSingleSubscriber.onSubscribe(BlockingSingleSubscriber.java:54) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.subscribe(Mono.java:4576) ~[reactor-core-3.7.5.jar:3.7.5]
	at reactor.core.publisher.Mono.block(Mono.java:1778) ~[reactor-core-3.7.5.jar:3.7.5]
	at io.modelcontextprotocol.server.transport.WebMvcSseServerTransport.handleMessage(WebMvcSseServerTransport.java:263) ~[mcp-spring-webmvc-0.7.0.jar:0.7.0]
	at org.springframework.web.servlet.function.support.HandlerFunctionAdapter.handle(HandlerFunctionAdapter.java:108) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) ~[tomcat-embed-core-10.1.40.jar:6.0]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.2.6.jar:6.2.6]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.40.jar:6.0]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.2.6.jar:6.2.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.6.jar:6.2.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.2.6.jar:6.2.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.6.jar:6.2.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.2.6.jar:6.2.6]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.6.jar:6.2.6]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.40.jar:10.1.40]
	at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na]

2025-05-07T21:33:54.042+02:00  WARN 64151 --- [nio-8080-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Ignoring exception, response committed already: org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class java.util.LinkedHashMap] with preset Content-Type 'text/event-stream'
2025-05-07T21:33:54.042+02:00  WARN 64151 --- [nio-8080-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class java.util.LinkedHashMap] with preset Content-Type 'text/event-stream']
2025-05-07T21:33:54.046+02:00 ERROR 64151 --- [nio-8080-exec-8] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session a2c209b5-4f6a-4675-8c4c-39733c6b5823: Cannot invoke "org.apache.catalina.connector.OutputBuffer.isBlocking()" because "this.ob" is null
2025-05-07T21:33:54.046+02:00 ERROR 64151 --- [nio-8080-exec-8] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 1c57403f-180f-4079-a8ca-b9554aaf383a: Cannot invoke "org.apache.catalina.connector.OutputBuffer.isBlocking()" because "this.ob" is null
2025-05-07T21:33:54.047+02:00 ERROR 64151 --- [nio-8080-exec-8] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 1ac5ae28-1763-40e3-b2d5-cc4ecb765d6a: ServletOutputStream failed to flush: java.io.IOException: Broken pipe
2025-05-07T21:33:54.047+02:00 ERROR 64151 --- [nio-8080-exec-8] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 5c0cb168-06fb-4981-83f2-604789055d4a: Response not usable after response errors.
2025-05-07T21:33:54.047+02:00 ERROR 64151 --- [nio-8080-exec-8] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 5e0c7216-87ce-4dc6-a418-de8e4297f5a8: Response not usable after response errors.
2025-05-07T21:33:54.048+02:00 ERROR 64151 --- [nio-8080-exec-3] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session a2c209b5-4f6a-4675-8c4c-39733c6b5823: Cannot invoke "org.apache.catalina.connector.OutputBuffer.isBlocking()" because "this.ob" is null
2025-05-07T21:33:54.048+02:00 ERROR 64151 --- [nio-8080-exec-7] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session a2c209b5-4f6a-4675-8c4c-39733c6b5823: Cannot invoke "org.apache.catalina.connector.OutputBuffer.isBlocking()" because "this.ob" is null
2025-05-07T21:33:54.048+02:00 ERROR 64151 --- [nio-8080-exec-3] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 1c57403f-180f-4079-a8ca-b9554aaf383a: Cannot invoke "org.apache.catalina.connector.OutputBuffer.isBlocking()" because "this.ob" is null
2025-05-07T21:33:54.048+02:00 ERROR 64151 --- [nio-8080-exec-7] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 1c57403f-180f-4079-a8ca-b9554aaf383a: Cannot invoke "org.apache.catalina.connector.OutputBuffer.isBlocking()" because "this.ob" is null
2025-05-07T21:33:54.048+02:00 ERROR 64151 --- [nio-8080-exec-3] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 1ac5ae28-1763-40e3-b2d5-cc4ecb765d6a: Response not usable after response errors.
2025-05-07T21:33:54.048+02:00 ERROR 64151 --- [nio-8080-exec-7] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 1ac5ae28-1763-40e3-b2d5-cc4ecb765d6a: Response not usable after response errors.
2025-05-07T21:33:54.048+02:00 ERROR 64151 --- [nio-8080-exec-3] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 2b39475b-90f9-4e6a-b2f6-fa9f92411205: ServletOutputStream failed to flush: java.io.IOException: Broken pipe
2025-05-07T21:33:54.048+02:00 ERROR 64151 --- [nio-8080-exec-7] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 2b39475b-90f9-4e6a-b2f6-fa9f92411205: ServletOutputStream failed to flush: java.io.IOException: Broken pipe
2025-05-07T21:33:54.048+02:00 ERROR 64151 --- [nio-8080-exec-3] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 5c0cb168-06fb-4981-83f2-604789055d4a: Response not usable after response errors.
2025-05-07T21:33:54.048+02:00 ERROR 64151 --- [nio-8080-exec-7] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 5c0cb168-06fb-4981-83f2-604789055d4a: Response not usable after response errors.
2025-05-07T21:33:54.048+02:00 ERROR 64151 --- [nio-8080-exec-3] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 5e0c7216-87ce-4dc6-a418-de8e4297f5a8: Response not usable after response errors.
2025-05-07T21:33:54.048+02:00 ERROR 64151 --- [nio-8080-exec-7] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session 5e0c7216-87ce-4dc6-a418-de8e4297f5a8: Response not usable after response errors.
2025-05-07T21:33:54.048+02:00 ERROR 64151 --- [nio-8080-exec-9] i.m.s.t.WebMvcSseServerTransport         : Failed to send message to session a2c209b5-4f6a-4675-8c4c-39733c6b5823: Cannot invoke "org.apache.catalina.connector.OutputBuffer.isBlocking()" because "this.ob" is null

Environment
Spring AI 1.0.0-M6, Spring Boot 3.4.5, Java 21

Steps to reproduce
Setup a Spring Boot project with Spring AI (WebMVC), implement a sample service annotated with @Tool and connect it to the Cursor AI (MCP Client)

Image

Image

Expected behavior
Not having error and warn logs and random disconnects.

Minimal Complete Reproducible example

https://github.com/jpomykala/spring-boot-ai-mcp-webmvc-sample

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions