apache/druid · error · IOException

failed to flush one or more emitters

Error message

failed to flush one or more emitters

What it means

SwitchingEmitter.flush() flushes each of its delegate emitters; if any delegate throws, it logs the failure and sets a fail flag, then after processing all delegates throws a single IOException('failed to flush one or more emitters'). The specific delegate's error is only available in the logged stack trace, so this exception aggregates any underlying flush failure (timeouts, interruptions, closed services).

Solutions

  1. Inspect the preceding 'Failed to flush emitter [%s]' log lines to identify which delegate failed and why.
  2. Fix the underlying delegate issue (network, flushTimeOut, endpoint availability).
  3. Catch IOException around flush()/close() in shutdown paths so one bad emitter doesn't abort shutdown.
  4. Test each delegate emitter's connectivity independently before wiring into SwitchingEmitter.

Example fix

// before
try { switchingEmitter.close(); } catch (Exception ignored) {}
// after
try {
  switchingEmitter.close();
} catch (IOException e) {
  log.error(e, "Some delegate emitters failed to flush; check delegate logs");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// proactively verify each delegate can flush
for (Emitter delegate : delegates) {
  try { delegate.flush(); } catch (IOException e) { log.error(e, "Delegate unhealthy: %s", delegate); }
}

Try / catch

try {
  switchingEmitter.flush();
} catch (IOException e) {
  // check 'Failed to flush emitter' log lines to find the failing delegate
  log.error(e, "One or more delegate emitters failed to flush");
}

Prevention

When it happens

Trigger: Calling flush() (or close(), which flushes) when any wrapped emitter — e.g. an HttpPostEmitter that timed out or a closed emitter — fails its own flush.

Common situations: Shutdown where the HTTP delegate can't reach the recipient; mixed delegate setup where one feed's emitter is misconfigured; periodic flush hitting a network outage.

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/84e3606ffbea7ae5. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/java/util/emitter/core/SwitchingEmitter.java:137

  @Override
  public void flush() throws IOException
  {
    boolean fail = false;
    log.info("Flushing Switching Emitter.");

    for (Emitter e : knownEmitters) {
      try {
        log.info("Flushing emitter %s.", e.getClass().getName());
        e.flush();
      }
      catch (IOException ex) {
        log.error(ex, "Failed to flush emitter [%s]", e.getClass().getName());
        fail = true;
      }
    }

    if (fail) {
      throw new IOException("failed to flush one or more emitters");
    }
  }

  /**
   * Closes all emitters that the SwitchingEmitter uses
   * @throws IOException
   */
  @Override
  @LifecycleStop
  public void close() throws IOException
  {
    boolean fail = false;
    log.info("Closing Switching Emitter.");

    for (Emitter e : knownEmitters) {
      try {
        log.info("Closing emitter %s.", e.getClass().getName());
        e.close();

View on GitHub (pinned to 9b90983fd2)