apache/druid · error · IllegalStateException

Emissions of events not successful

Error message

Emissions of events not successful[%d: %s], with message[%s].

What it means

After posting a batch, any non-2xx response (other than the specially handled 413) causes the EmittingThread to throw ISE('Emissions of events not successful[%d: %s], with message[%s].') including the status code, status text, and the response body. It means the remote endpoint refused the events — an application-level HTTP failure during metric delivery.

Solutions

  1. Check response body in the exception for the server's error detail and fix the root cause (auth, path, capacity).
  2. Verify recipientBaseUrl points at the correct, reachable events endpoint.
  3. Enable basic authentication/bearer config if the endpoint requires it.
  4. Add retry at the infrastructure level (or use retryingEmitter wrapper) for transient 5xx responses.

Example fix

// before
config: recipientBaseUrl = http://overlord:8090/druid/indexer/v1 (wrong path)
// after
config: recipientBaseUrl = http://overlord:8090/druid/indexer/v1/worker (correct endpoint)
Defensive patterns

Strategy: retry

Validate before calling

// health-check the recipient before relying on it
int status = new URL(config.getRecipientBaseUrl()).openConnection()
    .getInputStream() != null ? 200 : 500; // plus auth/path checks

Try / catch

try {
  emitter.emit(event);
} catch (IllegalStateException e) {
  if (e.getMessage().startsWith("Emissions of events not successful")) {
    // parse status code from message; retry transient 5xx via wrapper emitter
  }
}

Prevention

When it happens

Trigger: Recipient returns 4xx/5xx: auth failures (401/403), target service down (503), wrong recipientBaseUrl path (404), server errors while ingesting events.

Common situations: Misconfigured recipientBaseUrl; remote Druid overlord or metrics service overloaded; authentication/authorization changes on the receiving endpoint; transient 5xx during deploys.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/5c8bd57b0903eaef. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/java/util/emitter/core/HttpPostEmitter.java:809

              timeoutMillis
          );
        }
        throw e;
      }

      if (response.getStatusCode() == 413) {
        accountFailedSending(sendingStartMs);
        throw new ISE(
            "Received HTTP status 413 from [%s]. Batch size of [%d] may be too large, "
            + "try adjusting maxBatchSizeBatch property",
            config.getRecipientBaseUrl(),
            config.getMaxBatchSize()
        );
      }

      if (response.getStatusCode() / 100 != 2) {
        accountFailedSending(sendingStartMs);
        throw new ISE(
            "Emissions of events not successful[%d: %s], with message[%s].",
            response.getStatusCode(),
            response.getStatusText(),
            response.getResponseBody(StandardCharsets.UTF_8).trim()
        );
      }

      accountSuccessfulSending(sendingStartMs);
    }

    /**
     * This method computes the timeout for sending a batch of events over HTTP, based on how much time it took to
     * populate that batch. The idea is that if it took X milliseconds to fill the batch, we couldn't wait for more than
     * X * {@link HttpEmitterConfig#httpTimeoutAllowanceFactor} milliseconds to send that data, because at the same time
     * the next batch is probably being filled with the same speed, so we have to keep up with the speed.
     *
     * Ideally it should use something like moving average instead of plain last batch fill time in order to accomodate
     * for emitting bursts, but it might unnecessary because Druid application might not produce events in bursts.

View on GitHub (pinned to 9b90983fd2)