apache/druid · error · IOException
failed to close one or more emitters
Error message
failed to close one or more emitters
What it means
SwitchingEmitter routes events to one of several underlying emitters (alert, feed, etc.). During close(), it closes each child emitter; if any child throws an IOException, it remembers the failure and throws this aggregate IOException once all children have been attempted. It signals that at least one child emitter could not shut down cleanly, so buffered events may not have been flushed.
Source
Thrown at processing/src/main/java/org/apache/druid/java/util/emitter/core/SwitchingEmitter.java:164
@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();
}
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");
}
}
}
View on GitHub (pinned to 9b90983fd2)
Solutions
- Check the accompanying 'Failed to close emitter [<class>]' log lines to identify which child emitter(s) failed and fix the root cause (network, endpoint availability).
- Ensure the child emitters' target endpoints are reachable and draining correctly before/while shutting down the service.
- Verify close() is only called once per emitter lifecycle; avoid closing an already-closed emitter.
- If the failure is during process shutdown and data loss is acceptable for those metrics, this can often be logged and ignored.
- Flush or wait for the emitter's internal queue to drain (e.g. call flush() and wait) before close() to reduce failure risk.
Example fix
// before
switchingEmitter.close(); // may throw IOException, swallowing other pending shutdown work
// after
try {
emitter.flush();
switchingEmitter.close();
} catch (IOException e) {
log.warn(e, "Some emitters failed to close during shutdown; continuing");
} Defensive patterns
Strategy: try-catch
Validate before calling
// before close, ensure children can flush switchingEmitter.flush();
Try / catch
try {
switchingEmitter.close();
} catch (IOException e) {
log.warn(e, "Emitter close failed on shutdown; some events may not have been flushed");
} Prevention
- Register emitters in the Druid lifecycle so close happens once, in order, at shutdown
- Keep emitter endpoints healthy; monitor the target service availability
- Call flush() and let queues drain before close()
- Never close the same emitter twice
When it happens
Trigger: Calling SwitchingEmitter.close() when any wrapped emitter's close() throws IOException — typically a UriEmitter/HttpEmitter whose flush to its HTTP endpoint fails, or an emitter whose writer is already closed or errored.
Common situations: Druid service shutdown while the HTTP emitter's target (e.g. a metrics/alerting endpoint) is down or slow; double-close of emitters; disk or network issues preventing the child emitter from flushing its queue during close.
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
- failed to close one or more emitters
- Could not close channel for level [%d] and rank [%d]
- failed to flush one or more emitters
- error closing org.apache.druid.query.aggregation.Serializabl
- error closing org.apache.druid.query.aggregation.Serializabl
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/5d2b4d9048435924.
Report an issue: GitHub.