{"record":{"id":"f4932b487df70265","repo":"apache/shardingsphere","slug":"failed-to-start-s-server","errorCode":null,"errorMessage":"Failed to start %s server.","messagePattern":"Failed to start (.+?) server\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"critical","filePath":"mcp/bootstrap/src/main/java/org/apache/shardingsphere/mcp/bootstrap/MCPRuntimeLauncher.java","lineNumber":64,"sourceCode":"    \n    /**\n     * Launch.\n     *\n     * @param config launch configuration\n     * @return MCP Server\n     * @throws IOException when the active server startup fails\n     */\n    public MCPRuntimeServer launch(final MCPLaunchConfiguration config) throws IOException {\n        ShardingSpherePreconditions.checkNotNull(config, () -> new IllegalArgumentException(\"MCP launch configuration cannot be null.\"));\n        MCPRuntimeContext runtimeContext = new MCPRuntimeContext(new MCPSessionManager(config.getDatabases()), new MCPDatabaseCapabilityProvider(config.getDatabases()),\n                config.getTransportType());\n        MCPRuntimeServer result = isHttpTransport(config) ? new StreamableHttpMCPServer(config.getHttpTransport(), runtimeContext) : new StdioMCPServer(runtimeContext);\n        try {\n            result.start();\n            log.info(createStartupLogMessage(config, result));\n        } catch (final IOException ex) {\n            result.stop();\n            throw new IOException(String.format(\"Failed to start %s server.\", isHttpTransport(config) ? \"HTTP\" : \"STDIO\"), ex);\n        }\n        return result;\n    }\n    \n    private String createStartupLogMessage(final MCPLaunchConfiguration config, final MCPRuntimeServer server) {\n        return isHttpTransport(config) ? createHttpStartupLogMessage(config, (StreamableHttpMCPServer) server) : createStdioStartupLogMessage(config);\n    }\n    \n    private String createHttpStartupLogMessage(final MCPLaunchConfiguration config, final StreamableHttpMCPServer server) {\n        String endpoint = String.format(\"http://%s:%d%s\", config.getHttpTransport().getBindHost(), server.getLocalPort(), config.getHttpTransport().getEndpointPath());\n        SessionAttributionResolver sessionAttributionResolver = new SessionAttributionResolver(config.getHttpTransport().getSessionAttributionSource());\n        return String.format(\"ShardingSphere MCP Server started, transport=%s, config=%s, databases=%d, endpoint=%s, session_attribution=%s, logs=%s.\",\n                config.getTransportType().name().toLowerCase(Locale.ENGLISH), configPath, config.getDatabases().size(), endpoint, sessionAttributionResolver.getSummary(), LOG_PATH);\n    }\n    \n    private String createStdioStartupLogMessage(final MCPLaunchConfiguration config) {\n        return String.format(\"ShardingSphere MCP Server started, transport=%s, config=%s, databases=%d, logs=%s. Stdout is reserved for MCP protocol frames.\",\n                config.getTransportType().name().toLowerCase(Locale.ENGLISH), configPath, config.getDatabases().size(), LOG_PATH);","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/mcp/bootstrap/src/main/java/org/apache/shardingsphere/mcp/bootstrap/MCPRuntimeLauncher.java#L46-L82","documentation":"MCPRuntimeLauncher.launch() builds the runtime context, chooses a StreamableHttpMCPServer or StdioMCPServer from the transport type, and calls start(); if start() throws IOException, the launcher stops the partially started server and rethrows IOException('Failed to start %s server.'), naming HTTP or STDIO. The message is a wrapper — the attached cause carries the actual transport failure.","triggerScenarios":"Launching the ShardingSphere MCP server with an HTTP transport whose port is taken or bind host is invalid (delegated to the Tomcat-based server, which throws IOException), or with a STDIO transport where the standard streams cannot be acquired; any IOException from server.start() triggers the wrap after result.stop().","commonSituations":"Port already in use for the HTTP endpoint; bindHost set to an interface the host does not own; running in a container/sandbox where STDIO is detached; conflicting MCP instance on the same endpoint path; insufficient permission to create the temp directory used by the embedded server.","solutions":["Read the cause of the IOException (getCause) — it distinguishes port-in-use, bind failure, or stream problems.","Free the configured HTTP port or change it to an unused one, and set bindHost to a local interface (127.0.0.1 unless LAN exposure is intended).","For STDIO transport, run the launcher attached to real stdin/stdout (no daemonization) and keep logs on stderr only.","Ensure one MCP instance per endpoint; stop previous instances before relaunching.","Verify write access to the temp directory the embedded server uses."],"exampleFix":"# before\njava -jar shardingsphere-mcp.jar --transport http --port 8080   # port already bound\n\n# after\n# free the port or pick another\njava -jar shardingsphere-mcp.jar --transport http --bind-host 127.0.0.1 --port 18080","handlingStrategy":"try-catch","validationCode":"// before launch, verify the HTTP port is free\ntry (java.net.ServerSocket probe = new java.net.ServerSocket(port, 1, InetAddress.getByName(bindHost))) { /* port free */ }","typeGuard":null,"tryCatchPattern":"try { MCPRuntimeServer server = launcher.launch(config); } catch (final IOException ex) { Throwable cause = ex.getCause(); /* cause distinguishes port bind vs stdio vs temp-dir failure */ }","preventionTips":["Pre-check port availability and bind-host validity for HTTP transport.","Run STDIO transport attached to real stdin/stdout with logs on stderr.","Ensure only one MCP instance per endpoint and a writable temp dir.","Always inspect the cause, not just the wrapper message."],"tags":["mcp","startup","server","io","transport"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}