Skip to content

Streamable HTTP - SSE Failure Logging / Handling #877

Closed

Description

@jamesward

Version 1.1.0

I'm connecting to the https://www.javadocs.dev/mcp server - streamable http, but no SSE support. I get this on Spring app startup:

2026-03-19T21:33:47.310-06:00  INFO 114327 --- [ient-1-Worker-0] i.m.client.LifecycleInitializer          : Server response with Protocol: 2025-03-26, Capabilities: ServerCapabilities[completions=null, experimental=null, logging=null, prompts=null, resources=null, tools=ToolCapabilities[listChanged=false]], Info: Implementation[name=javadocs.dev, title=null, version=0.0.2] and Instructions null
2026-03-19T21:33:47.318-06:00  WARN 114327 --- [ient-1-Worker-0] i.m.client.LifecycleInitializer          : Handling exception

io.modelcontextprotocol.spec.McpTransportException: Unrecognized server error when connecting to SSE stream, status code: 404
	at io.modelcontextprotocol.client.transport.HttpClientStreamableHttpTransport.lambda$reconnect$11(HttpClientStreamableHttpTransport.java:303) ~[mcp-core-1.1.0.jar:1.1.0]
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:389) ~[reactor-core-3.8.4.jar:3.8.4]
	at reactor.core.publisher.FluxCreate$BufferAsyncSink.drain(FluxCreate.java:887) ~[reactor-core-3.8.4.jar:3.8.4]
	at reactor.core.publisher.FluxCreate$BufferAsyncSink.next(FluxCreate.java:812) ~[reactor-core-3.8.4.jar:3.8.4]
	at reactor.core.publisher.FluxCreate$SerializedFluxSink.next(FluxCreate.java:164) ~[reactor-core-3.8.4.jar:3.8.4]
	at io.modelcontextprotocol.client.transport.ResponseSubscribers$BodilessResponseLineSubscriber.hookOnComplete(ResponseSubscribers.java:315) ~[mcp-core-1.1.0.jar:1.1.0]
	at reactor.core.publisher.BaseSubscriber.onComplete(BaseSubscriber.java:200) ~[reactor-core-3.8.4.jar:3.8.4]
	at org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber.onComplete(FlowAdapters.java:221) ~[reactive-streams-1.0.4.jar:na]
	at java.net.http/jdk.internal.net.http.LineSubscriberAdapter$LineSubscription.loop(LineSubscriberAdapter.java:430) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:280) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:233) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.LineSubscriberAdapter$LineSubscription.signalComplete(LineSubscriberAdapter.java:193) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.LineSubscriberAdapter.onComplete(LineSubscriberAdapter.java:114) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.HttpBodySubscriberWrapper.complete(HttpBodySubscriberWrapper.java:293) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.HttpBodySubscriberWrapper.onComplete(HttpBodySubscriberWrapper.java:401) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.Stream.schedule(Stream.java:230) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:280) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:233) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.Stream.receiveDataFrame(Stream.java:427) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.Stream.incoming(Stream.java:566) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.Http2Connection.processFrame(Http2Connection.java:1070) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.frame.FramesDecoder.decode(FramesDecoder.java:155) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.Http2Connection$FramesController.processReceivedData(Http2Connection.java:318) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.Http2Connection.asyncReceive(Http2Connection.java:871) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.processQueue(Http2Connection.java:1840) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:280) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:233) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.runOrSchedule(Http2Connection.java:1857) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.onNext(Http2Connection.java:1884) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.Http2Connection$Http2TubeSubscriber.onNext(Http2Connection.java:1818) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SSLTube$DelegateWrapper.onNext(SSLTube.java:219) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SSLTube$SSLSubscriberWrapper.onNext(SSLTube.java:499) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SSLTube$SSLSubscriberWrapper.onNext(SSLTube.java:304) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher.run1(SubscriberWrapper.java:316) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher.run(SubscriberWrapper.java:259) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:280) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(SequentialScheduler.java:233) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SubscriberWrapper.outgoing(SubscriberWrapper.java:232) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SubscriberWrapper.outgoing(SubscriberWrapper.java:198) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:465) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:283) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149) ~[java.net.http:na]
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207) ~[java.net.http:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614) ~[na:na]
	at java.base/java.lang.Thread.run(Thread.java:1474) ~[na:na]

Everything works correctly. The MCP spec does say that the GET to /mcp can return a 405 response, which I tried but still got a similar logged error.

Activity

  1. self-assigned this
    on Mar 21, 2026
  2. Kehrlann commented on Apr 1, 2026

    @Kehrlann
    Contributor

    Issue introduced in #861

  3. added theissue type on Apr 1, 2026
  4. added
    bugSomething isn't working
    P3Nice to haves, rare edge cases
    on Apr 1, 2026
  5. Kehrlann commented on Apr 2, 2026

    @Kehrlann
    Contributor

    @jamesward I'd be inclined to leave the 404 error as-is, but respect HTTP 405. Would that be acceptable?

  6. added a commit that references this issue on Apr 2, 2026
    4867755
  7. jamesward commented on Apr 2, 2026

    @jamesward
    ContributorAuthor

    I think that sounds like a spec-compliant approach. So that'd be good! Thank you.

  8. added 2 commits that reference this issue on Apr 2, 2026
    b325ace
    8e1c5d0
  9. Kehrlann commented on Apr 2, 2026

    @Kehrlann
    Contributor

    Fixed in #900 , forward ported to 5e77762

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P3Nice to haves, rare edge casesbugSomething isn't working

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions