apache/druid · error · RejectedExecutionException
Service is not started.
Error message
Service is not started.
What it means
HttpPostEmitter.awaitStarted() waits up to 1 second for the emitter's start latch. If the emitter was never started (or hasn't started within 1s), emit/flush attempts throw RejectedExecutionException 'Service is not started.' This prevents silently queuing events into an emitter that will never send them.
Source
Thrown at processing/src/main/java/org/apache/druid/java/util/emitter/core/HttpPostEmitter.java:205
public void start()
{
synchronized (startLock) {
if (!running) {
if (startLatch.getCount() == 0) {
throw new IllegalStateException("Already started.");
}
running = true;
startLatch.countDown();
emittingThread.start();
}
}
}
private void awaitStarted()
{
try {
if (!startLatch.await(1, TimeUnit.SECONDS)) {
throw new RejectedExecutionException("Service is not started.");
}
if (isTerminated()) {
throw new RejectedExecutionException("Service is closed.");
}
}
catch (InterruptedException e) {
log.debug("Interrupted waiting for start");
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
private boolean isTerminated()
{
return concurrentBatch.get() == null;
}
@OverrideView on GitHub (pinned to 9b90983fd2)
Solutions
- Call emitter.start() before emitting or flushing any events
- Ensure startup isn't delayed beyond 1 second (check the EmittingThread for blocking initialization)
- Check for a prior close/termination that stopped the service; create a fresh emitter if needed
- Catch RejectedExecutionException around emit/flush to detect lifecycle misuse and requeue or log
Example fix
// before HttpPostEmitter emitter = new HttpPostEmitter(config, mapper); emitter.emit(event); // RejectedExecutionException // after HttpPostEmitter emitter = new HttpPostEmitter(config, mapper); emitter.start(); emitter.emit(event);
Defensive patterns
Strategy: try-catch
Validate before calling
if (!emitter.isStarted()) {
emitter.start(); // or await startup before emitting
} Try / catch
try {
emitter.emit(event);
} catch (RejectedExecutionException e) {
log.warn("Emitter not started; starting and re-emitting");
emitter.start();
emitter.emit(event);
} Prevention
- Always call start() immediately after constructing HttpPostEmitter
- Route emits through Lifecycle so ordering guarantees start-before-emit
- Investigate slow EmittingThread startup if the 1s await is exceeded
- In tests, start the emitter in setup before any emit/flush calls
When it happens
Trigger: Calling emit(), flush() (via emitAndReturnBatch/flush -> awaitStarted) on an HttpPostEmitter before start() was called, or when start() has not completed within the 1-second await window.
Common situations: Forgetting lifecycle start in embedded usage; emitting immediately after construction; a blocked or slow startup thread exceeding the 1s latch timeout; emitter created but start() skipped in tests.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/5dac0d5ba285835c.
Report an issue: GitHub.