elastic/elasticsearch · error · IllegalStateException
MockApmServer not started
Error message
MockApmServer not started
What it means
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.
Source
Thrown at build-tools/src/main/java/org/elasticsearch/gradle/testclusters/MockApmServer.java:117
*/
public void start() throws IOException {
if (instance != null) {
throw new IllegalStateException("MockApmServer already started");
}
InetSocketAddress addr = new InetSocketAddress("0.0.0.0", 0);
HttpServer server = HttpServer.create(addr, 10);
server.createContext("/", new RootHandler());
server.start();
instance = server;
logger.lifecycle("MockApmServer started on port " + server.getAddress().getPort());
grpcInstance = ServerBuilder.forPort(0).addService(new GrpcMetricsService()).addService(new GrpcTraceService()).build().start();
logger.lifecycle("MockApmServer gRPC (OTLP metrics + traces) started on port " + grpcInstance.getPort());
}
public int getPort() {
if (instance == null) {
throw new IllegalStateException("MockApmServer not started");
}
return instance.getAddress().getPort();
}
public int getGrpcPort() {
if (grpcInstance == null) {
throw new IllegalStateException("MockApmServer not started");
}
return grpcInstance.getPort();
}
/**
* Stop the server gracefully if possible
*/
public void stop() {
if (instance != null) {
logger.lifecycle("stopping apm server");
instance.stop(1);View on GitHub (pinned to db6a809a66)
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()'.
Example fix
// before:
mockServer.start();
int p = mockServer.getPort(); // ok only if start succeeded
// guard:
if (mockServer != null) {
mockServer.start();
int p = mockServer.getPort();
} Defensive patterns
Strategy: type-guard
Validate before calling
if (instance == null) {
throw new IllegalStateException("Call start() before getPort()");
} Type guard
boolean httpStarted(MockApmServer s) { return s != null && s.instanceFieldNotNull(); } // conceptual — instance is private; expose isStarted() Prevention
- Sequence start() before any getPort() call.
- After stop(), create a new MockApmServer rather than reusing.
- Add an isStarted() helper if you must guard externally.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- MockApmServer already started
- Configuration for {} can not be altered, already locked
- Cannot add nodes to test cluster after is has been frozen
- Configuration for {} can not be altered, already locked
- Can't treat {} as single node as it has {} nodes
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/ec2e7abe5d55157e.
Report an issue: GitHub.