{"record":{"id":"ec2e7abe5d55157e","repo":"elastic/elasticsearch","slug":"mockapmserver-not-started","errorCode":null,"errorMessage":"MockApmServer not started","messagePattern":"MockApmServer not started","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"build-tools/src/main/java/org/elasticsearch/gradle/testclusters/MockApmServer.java","lineNumber":117,"sourceCode":"     */\n    public void start() throws IOException {\n        if (instance != null) {\n            throw new IllegalStateException(\"MockApmServer already started\");\n        }\n        InetSocketAddress addr = new InetSocketAddress(\"0.0.0.0\", 0);\n        HttpServer server = HttpServer.create(addr, 10);\n        server.createContext(\"/\", new RootHandler());\n        server.start();\n        instance = server;\n        logger.lifecycle(\"MockApmServer started on port \" + server.getAddress().getPort());\n\n        grpcInstance = ServerBuilder.forPort(0).addService(new GrpcMetricsService()).addService(new GrpcTraceService()).build().start();\n        logger.lifecycle(\"MockApmServer gRPC (OTLP metrics + traces) started on port \" + grpcInstance.getPort());\n    }\n\n    public int getPort() {\n        if (instance == null) {\n            throw new IllegalStateException(\"MockApmServer not started\");\n        }\n        return instance.getAddress().getPort();\n    }\n\n    public int getGrpcPort() {\n        if (grpcInstance == null) {\n            throw new IllegalStateException(\"MockApmServer not started\");\n        }\n        return grpcInstance.getPort();\n    }\n\n    /**\n     * Stop the server gracefully if possible\n     */\n    public void stop() {\n        if (instance != null) {\n            logger.lifecycle(\"stopping apm server\");\n            instance.stop(1);","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools/src/main/java/org/elasticsearch/gradle/testclusters/MockApmServer.java#L99-L135","documentation":"Thrown by MockApmServer.getPort() when the 'instance' field (the HttpServer) is null — i.e. getPort() was called before start() bound the HTTP server, or after stop() nulled it. The method has no fallback: it needs the live HttpServer's bound port.","triggerScenarios":"Calling mockServer.getPort() before mockServer.start(), or after stop() set instance=null. The HttpServer only has a concrete port after server.start() binds to 0.0.0.0:0.","commonSituations":"Test code or a build hook that queries the APM port before the RunTask has started the mock; reusing the MockApmServer across a stop/start cycle without re-initialising.","solutions":["Ensure start() completes before any getPort() call — sequence them explicitly.","After stop(), do not call getPort(); create a new MockApmServer and start() it first.","If unsure of state, add a guard: 'if (mockServer != null && mockServer.isStarted()) mockServer.getPort()'."],"exampleFix":"// before:\nmockServer.start();\nint p = mockServer.getPort();  // ok only if start succeeded\n// guard:\nif (mockServer != null) {\n    mockServer.start();\n    int p = mockServer.getPort();\n}","handlingStrategy":"type-guard","validationCode":"if (instance == null) {\n    throw new IllegalStateException(\"Call start() before getPort()\");\n}","typeGuard":"boolean httpStarted(MockApmServer s) { return s != null && s.instanceFieldNotNull(); } // conceptual — instance is private; expose isStarted()","tryCatchPattern":null,"preventionTips":["Sequence start() before any getPort() call.","After stop(), create a new MockApmServer rather than reusing.","Add an isStarted() helper if you must guard externally."],"tags":["testclusters","apm","lifecycle","api-misuse"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}