apache/shenyu · error · IllegalStateException
Failed to extract session ID from MCP exchange. This may…
Error message
Failed to extract session ID from MCP exchange. This may indicate an SDK compatibility issue. Tested SDK version: ${McpSessionHelper.getSupportedSdkVersion()}. Original error: ${e.getMessage()} What it means
Wrapper IllegalStateException thrown by ShenyuToolCallback.extractSessionId when the original RuntimeException is detected (via isSdkCompatibilityError, message prefixed 'SDK COMPATIBILITY ERROR') as an MCP SDK compatibility failure. It rethrows the underlying session-extraction error with the tested SDK version and the original message so the developer can identify a version mismatch between the io.modelcontextprotocol MCP SDK and what ShenYu supports (0.17.0).
Solutions
- Pin the MCP SDK (io.modelcontextprotocol:mcp) to 0.17.0 / the version McpSessionHelper.SUPPORTED_SDK_VERSION reports and rebuild
- Check startup logs for 'SDK COMPATIBILITY ERROR: Failed to resolve reflection fields' to see the missing field, then upgrade or downgrade ShenYu's mcp-server plugin to match the SDK
- Remove the security manager or add JPMS --add-opens for io.modelcontextprotocol classes if reflection is blocked
- Keep Spring AI (tested 1.1.2) and MCP SDK versions aligned via one BOM to avoid transitive drift
Example fix
// before (pom.xml) <dependency><groupId>io.modelcontextprotocol.sdk</groupId><artifactId>mcp</artifactId><version>0.99.0</version></dependency> // after <dependency><groupId>io.modelcontextprotocol.sdk</groupId><artifactId>mcp</artifactId><version>0.17.0</version></dependency>
Defensive patterns
Strategy: try-catch
Validate before calling
if (!McpSessionHelper.isReflectionAvailable()) {
throw new IllegalStateException("MCP SDK incompatible; tested version: " + McpSessionHelper.getSupportedSdkVersion());
} Try / catch
try {
String sessionId = McpSessionHelper.getSessionId(mcpExchange);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("SDK COMPATIBILITY ERROR")
|| e.getMessage().contains("Failed to extract session ID")) {
LOG.error("MCP SDK version mismatch; tested: " + McpSessionHelper.getSupportedSdkVersion(), e);
} else { throw e; }
} Prevention
- Pin io.modelcontextprotocol:mcp and Spring AI to the tested versions via dependencyManagement
- Fail fast at startup when McpSessionHelper.isReflectionAvailable() is false
- Watch transitive dependency upgrades (Spring AI BOM) that silently bump the MCP SDK
When it happens
Trigger: During extractSessionId, McpSessionHelper throws an SDK COMPATIBILITY ERROR IllegalStateException — i.e. reflection fields (McpSyncServerExchange.exchange / McpAsyncServerExchange.session) failed to resolve or an IllegalAccessException occurred — because the runtime MCP SDK version differs from 0.17.0 or blocks reflection.
Common situations: Dependency-management (BOM/Spring AI) upgrades pulling a newer MCP SDK; a security manager or JPMS module restrictions blocking setAccessible; snapshot dependency drift between admin and gateway modules.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- SDK COMPATIBILITY ERROR: Failed to access SDK internal…
- SDK COMPATIBILITY ERROR: MCP SDK reflection fields are not…
- McpAsyncServerExchange is required in McpSyncServerExchange
- Session is required in McpAsyncServerExchange
- Import mcp server config failed:
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/3d6efa9288ac4fcc.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/callback/ShenyuToolCallback.java:786
* @return the session ID
* @throws IllegalStateException if the session ID is blank or an SDK compatibility issue blocks extraction
* @throws IllegalArgumentException if the exchange is missing required session state
*/
private String extractSessionId(final McpSyncServerExchange mcpExchange) {
try {
final String sessionId = McpSessionHelper.getSessionId(mcpExchange);
if (StringUtils.hasText(sessionId)) {
LOG.debug("Extracted session ID: {}", sessionId);
return sessionId;
}
throw new IllegalStateException("Session ID is empty – it should have been set earlier by handleMessageEndpoint");
} catch (RuntimeException e) {
if (!isSdkCompatibilityError(e)) {
throw e;
}
// Re-throw SDK compatibility errors with additional context.
throw new IllegalStateException(
"Failed to extract session ID from MCP exchange. "
+ "This may indicate an SDK compatibility issue. "
+ "Tested SDK version: " + McpSessionHelper.getSupportedSdkVersion() + ". "
+ "Original error: " + e.getMessage(), e);
}
}
private boolean isSdkCompatibilityError(final RuntimeException exception) {
return exception instanceof IllegalStateException
&& StringUtils.hasText(exception.getMessage())
&& exception.getMessage().startsWith(SDK_COMPATIBILITY_ERROR_PREFIX);
}
/**
* Gets the origin ServerWebExchange for the given session ID.
*
* @param sessionId the session ID
* @return the origin ServerWebExchangeView on GitHub (pinned to 567142e072)