spring-projects/spring-ai · warning
Got error when closing transport
Error message
Got error when closing transport
What it means
WebClientStreamableHttpTransport.createTransportSession() builds a Mono that DELETEs the MCP endpoint when a transport session closes. Errors from that close request are logged at WARN ('Got error when closing transport') and swallowed via onErrorComplete — the close failure does not propagate to the caller.
Source
Thrown at mcp/transport/mcp-spring-webflux/src/main/java/org/springframework/ai/mcp/client/webflux/transport/WebClientStreamableHttpTransport.java:184
this.handler.set(handler);
if (this.openConnectionOnStartup) {
logger.debug("Eagerly opening connection on startup");
return this.reconnect(null).then();
}
return Mono.empty();
});
}
private McpTransportSession<Disposable> createTransportSession() {
Function<String, Publisher<Void>> onClose = sessionId -> sessionId == null ? Mono.empty()
: this.webClient.delete()
.uri(this.endpoint)
.header(HttpHeaders.MCP_SESSION_ID, sessionId)
.header(HttpHeaders.PROTOCOL_VERSION, this.latestSupportedProtocolVersion)
.retrieve()
.toBodilessEntity()
.onErrorComplete(e -> {
logger.warn("Got error when closing transport", e);
return true;
})
.then();
return new DefaultMcpTransportSession(onClose);
}
@Override
public void setExceptionHandler(Consumer<Throwable> handler) {
logger.debug("Exception handler registered");
this.exceptionHandler.set(handler);
}
private void handleException(Throwable t) {
if (logger.isDebugEnabled()) {
logger.debug("Handling exception for session " + sessionIdOrPlaceholder(this.activeSession.get()), t);
}
if (t instanceof McpTransportSessionNotFoundException) {
McpTransportSession<?> invalidSession = this.activeSession.getAndSet(createTransportSession());View on GitHub (pinned to 98a7beda4f)
Solutions
- Treat it as benign if it occurs during application shutdown against an already-dead server — the session is gone either way.
- If frequent, verify the MCP server supports DELETE-based session termination per the MCP streamable HTTP spec.
- Check connectivity/auth to this.endpoint and that the server honors the Mcp-Session-Id header.
- Upgrade spring-ai MCP transport versions if the server returns unexpected status codes on close.
Defensive patterns
Strategy: fallback
Try / catch
// already handled internally via onErrorComplete; on your side: mcpClient.close() inside try/finally and ignore close-time warnings
Prevention
- Close MCP clients explicitly at shutdown so sessions terminate before the server disappears
- Confirm the MCP server supports DELETE session termination (streamable HTTP spec)
- Expect this WARN when the server restarted; reinitialize a fresh session instead of reusing the old one
When it happens
Trigger: Any MCP client session over the streamable HTTP (WebFlux) transport being closed/disposed while the server is unreachable, has already terminated the session (404 on unknown session id), or rejects the DELETE (auth failure).
Common situations: MCP server restarted or redeployed, invalidating the session id; network drop during shutdown; server not implementing session termination; closing the client after the server already ended the session.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- McpTransportSessionClosedException
- Method must not be null
- Method must have either 1 parameter (LoggingMessageNotificat
- Single parameter must be of type LoggingMessageNotification:
- First parameter must be of type LoggingLevel:
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/235e7eb1b852daa9.
Report an issue: GitHub.