{"record":{"id":"68e92a8e05dfe08d","repo":"apache/shardingsphere","slug":"failed-to-start-embedded-tomcat-runtime","errorCode":null,"errorMessage":"Failed to start embedded Tomcat runtime.","messagePattern":"Failed to start embedded Tomcat runtime\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"critical","filePath":"mcp/bootstrap/src/main/java/org/apache/shardingsphere/mcp/bootstrap/transport/server/http/StreamableHttpMCPServer.java","lineNumber":88,"sourceCode":"        }\n    }\n    \n    private void startEmbeddedTomcat() throws IOException {\n        try {\n            tomcat = new Tomcat();\n            connector = new Connector();\n            connector.setPort(config.getPort());\n            connector.setProperty(\"address\", config.getBindHost());\n            tomcat.setConnector(connector);\n            baseDirectory = Files.createTempDirectory(\"shardingsphere-mcp-tomcat\");\n            tomcat.setBaseDir(baseDirectory.toString());\n            Context context = tomcat.addContext(\"\", baseDirectory.toString());\n            ((StandardContext) context).setClearReferencesRmiTargets(false);\n            registerTransportServlet(context);\n            tomcat.start();\n        } catch (final LifecycleException ex) {\n            stop();\n            throw new IOException(\"Failed to start embedded Tomcat runtime.\", ex);\n        }\n    }\n    \n    private void registerTransportServlet(final Context context) {\n        Wrapper servletWrapper = Tomcat.addServlet(context, \"mcp-streamable-http\", transportServlet);\n        servletWrapper.setAsyncSupported(true);\n        context.addServletMappingDecoded(config.getEndpointPath(), \"mcp-streamable-http\");\n    }\n    \n    @Override\n    public void stop() {\n        closeTomcat();\n        closeSyncServer();\n        connector = null;\n        deleteBaseDirectory();\n    }\n    \n    private void closeTomcat() {","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/mcp/bootstrap/src/main/java/org/apache/shardingsphere/mcp/bootstrap/transport/server/http/StreamableHttpMCPServer.java#L70-L106","documentation":"StreamableHttpMCPServer.start() assembles an embedded Tomcat (connector on the configured port/bind host, temp base dir, transport servlet mapped at the endpoint path) and calls tomcat.start(). A Tomcat LifecycleException — most commonly a bind failure — is caught, stop() is invoked to release partial state, and the error is rethrown as IOException('Failed to start embedded Tomcat runtime.').","triggerScenarios":"Launching the MCP HTTP transport when the configured port is already bound, the bindHost address is not assigned to the host, or the temp base directory cannot be created; Tomcat then throws LifecycleException from start(), which this handler converts to IOException.","commonSituations":"Another MCP instance or unrelated service on the same port; bindHost set to 0.0.0.0-alikes or an interface absent in the container; read-only or full /tmp preventing Files.createTempDirectory; SELinux/AppArmor blocking the embedded Tomcat.","solutions":["Check the IOException's cause — LifecycleException text names bind vs. lifecycle failure.","Free the port (ss -ltnp / lsof -i :<port>) or configure an unused one.","Set bindHost to an address that exists on the machine (127.0.0.1 for local-only use).","Ensure the temp directory is writable and not exhausted; set a writable java.io.tmpdir if needed.","Run only one HTTP MCP server per port/endpoint path."],"exampleFix":"# before\n# port 8080 already in use -> IOException \"Failed to start embedded Tomcat runtime.\"\n\n# after\nss -ltnp | grep 8080    # find and stop the conflicting process, or:\njava -jar mcp.jar --transport http --bind-host 127.0.0.1 --port 18080","handlingStrategy":"validation","validationCode":"// before start: confirm the endpoint address is bindable\ntry (java.net.ServerSocket probe = new java.net.ServerSocket(port, 1, InetAddress.getByName(bindHost))) { /* bind will succeed */ } catch (final java.net.BindException ex) { throw new IllegalStateException(\"Port/host unavailable: \" + bindHost + \":\" + port, ex); }","typeGuard":null,"tryCatchPattern":"try { server.start(); } catch (final IOException ex) { Throwable cause = ex.getCause(); /* LifecycleException cause: free the port, fix bindHost, ensure temp dir writable */ }","preventionTips":["Reserve and pre-check the HTTP port before startup.","Bind to an interface that exists (127.0.0.1 for local-only).","Keep the temp directory writable and not full.","Run one MCP HTTP server per port/endpoint and stop stale instances first."],"tags":["mcp","tomcat","http","startup","port","bind"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}