{"record":{"id":"9de1d6d45c1387fe","repo":"spring-projects/spring-ai","slug":"notification-sentmessage-received-non-complia","errorCode":null,"errorMessage":"Notification: + sentMessage + received non-compliant response: + responseMessage","messagePattern":"Notification: \\+ sentMessage \\+ received non-compliant response: \\+ responseMessage","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"mcp/transport/mcp-spring-webflux/src/main/java/org/springframework/ai/mcp/client/webflux/transport/WebClientStreamableHttpTransport.java","lineNumber":519,"sourceCode":"\t\treturn response.statusCode().isSameCodeAs(HttpStatus.METHOD_NOT_ALLOWED);\n\t}\n\n\tprivate static boolean isEventStream(ClientResponse response) {\n\t\treturn response.statusCode().is2xxSuccessful() && response.headers().contentType().isPresent()\n\t\t\t\t&& response.headers().contentType().get().isCompatibleWith(MediaType.TEXT_EVENT_STREAM);\n\t}\n\n\tprivate static String sessionIdOrPlaceholder(McpTransportSession<?> transportSession) {\n\t\treturn transportSession.sessionId().orElse(MISSING_SESSION_ID);\n\t}\n\n\tprivate Flux<McpSchema.JSONRPCMessage> directResponseFlux(McpSchema.JSONRPCMessage sentMessage,\n\t\t\tClientResponse response) {\n\t\treturn response.bodyToMono(String.class).<Iterable<McpSchema.JSONRPCMessage>>handle((responseMessage, s) -> {\n\t\t\ttry {\n\t\t\t\tif (sentMessage instanceof McpSchema.JSONRPCNotification) {\n\t\t\t\t\tif (logger.isWarnEnabled()) {\n\t\t\t\t\t\tlogger.warn(\"Notification: \" + sentMessage + \" received non-compliant response: \"\n\t\t\t\t\t\t\t\t+ (Utils.hasText(responseMessage) ? responseMessage : \"[empty]\"));\n\t\t\t\t\t}\n\t\t\t\t\ts.complete();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tMcpSchema.JSONRPCMessage jsonRpcResponse = McpSchema.deserializeJsonRpcMessage(this.jsonMapper,\n\t\t\t\t\t\t\tresponseMessage);\n\t\t\t\t\ts.next(List.of(jsonRpcResponse));\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (IOException e) {\n\t\t\t\ts.error(new McpTransportException(e));\n\t\t\t}\n\t\t}).flatMapIterable(Function.identity());\n\t}\n\n\tprivate Flux<McpSchema.JSONRPCMessage> newEventStream(ClientResponse response, String sessionRepresentation) {\n\t\tMcpTransportStream<Disposable> sessionStream = new DefaultMcpTransportStream<>(this.resumableStreams,","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/transport/mcp-spring-webflux/src/main/java/org/springframework/ai/mcp/client/webflux/transport/WebClientStreamableHttpTransport.java#L501-L537","documentation":"A warning in directResponseFlux when an HTTP POST returning a direct (non-stream) response body gets a body even though the sent message was a JSON-RPC notification. Per the MCP Streamable HTTP spec, notifications must receive 202 with no body, so any non-empty body is flagged as a non-compliant response and the flux completes normally, discarding the body.","triggerScenarios":"Server responds 200 with a JSON body to a notification POST; a proxy rewrites 202 responses into 200 with a body; server transport implementation not following the notification-202 rule.","commonSituations":"Custom or hand-rolled MCP servers replying to notifications; gateway/proxy middleware adding response bodies; older server versions predating strict Streamable HTTP compliance.","solutions":["Fix the server (or update its MCP transport) to return HTTP 202 with an empty body for notifications","Check intermediary proxies/gateways for response body injection or status rewriting","Ignore the warning if harmless, but verify notifications are actually processed server-side","Test with the reference MCP server implementation to isolate compliance issues"],"exampleFix":"// before\n// server: return ok().body(\"accepted\", String.class) for notifications\n// after\n// server: return ResponseEntity.accepted().build(); // 202, no body for notifications","handlingStrategy":"fallback","validationCode":null,"typeGuard":"boolean isNotification(McpSchema.JSONRPCMessage m) {\n    return m instanceof McpSchema.JSONRPCNotification;\n}\n// only send notifications expecting no response body","tryCatchPattern":null,"preventionTips":["Return 202 with an empty body for notification POSTs in custom servers","Audit proxies for response rewriting","Test against the reference MCP server for compliance","Keep server transport libraries up to date"],"tags":["mcp","protocol-compliance","notification","http"],"backgroundTag":"unexpected-response-shape","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}