apache/druid · error · IOException

failed to close one or more emitters

Error message

failed to close one or more emitters

What it means

ComposingEmitter.close() attempts to close each child emitter; if any child close fails it logs the failure and, after processing all children, throws IOException 'failed to close one or more emitters'. This guarantees all children get a close attempt while still surfacing resource-cleanup problems to the caller.

Source

Thrown at processing/src/main/java/org/apache/druid/java/util/emitter/core/ComposingEmitter.java:102

  @LifecycleStop
  public void close() throws IOException
  {
    boolean fail = false;
    log.info("Closing Composing Emitter.");

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

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

  @Override
  public String toString()
  {
    return "ComposingEmitter{" +
           "emitters=" + emitters +
           '}';
  }
}

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Check logs for 'Failed to close emitter [...]' to find the offending child emitter
  2. Ensure the recipient endpoints are reachable at shutdown so the final flush inside close succeeds
  3. Call flush() before close() to reduce the work close must do
  4. Catch and log IOException from close in shutdown hooks so remaining cleanup still runs

Example fix

// before
emitter.close(); // throws if any child fails
// after
try {
  emitter.close();
} catch (IOException e) {
  log.error(e, "Some emitters failed to close");
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  emitter.close();
} catch (IOException e) {
  log.error(e, "One or more emitters failed to close; possible event loss");
}

Prevention

When it happens

Trigger: Calling close() on a ComposingEmitter when at least one wrapped emitter's close() throws (e.g. HttpPostEmitter's terminating flush fails, socket close errors).

Common situations: Application shutdown with a dead HTTP recipient causing the final flush inside close to fail; double-close of a child emitter; interrupted emitting thread refusing to terminate.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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