{"record":{"id":"be84db3613419f05","repo":"apache/iceberg","slug":"failed-to-notify-event-listeners","errorCode":null,"errorMessage":"Failed to notify event listeners","messagePattern":"Failed to notify event listeners","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/src/main/java/org/apache/iceberg/SnapshotProducer.java","lineNumber":568,"sourceCode":"              deleteFile(manifestList);\n            }\n          }\n        } else {\n          // saved may not be present if the latest metadata couldn't be loaded due to eventual\n          // consistency problems in refresh. in that case, don't clean up.\n          LOG.warn(\"Failed to load committed snapshot, skipping manifest clean-up\");\n        }\n      } catch (Throwable e) {\n        LOG.warn(\n            \"Failed to load committed table metadata or during cleanup, skipping further cleanup\",\n            e);\n      }\n    }\n\n    try {\n      notifyListeners();\n    } catch (Throwable e) {\n      LOG.warn(\"Failed to notify event listeners\", e);\n    }\n  }\n\n  private void notifyListeners() {\n    try {\n      Object event = updateEvent();\n      if (event != null) {\n        Listeners.notifyAll(event);\n\n        if (event instanceof CreateSnapshotEvent) {\n          CreateSnapshotEvent createSnapshotEvent = (CreateSnapshotEvent) event;\n\n          reporter.report(\n              ImmutableCommitReport.builder()\n                  .tableName(createSnapshotEvent.tableName())\n                  .snapshotId(createSnapshotEvent.snapshotId())\n                  .operation(createSnapshotEvent.operation())\n                  .sequenceNumber(createSnapshotEvent.sequenceNumber())","sourceCodeStart":550,"sourceCodeEnd":586,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/SnapshotProducer.java#L550-L586","documentation":"After a snapshot commit completes, SnapshotProducer.commit() fires listener events (e.g. commit metrics/reporting callbacks). If notifyListeners() throws any Throwable, it is caught and logged as this warning. The commit itself has already succeeded; only event notification to registered listeners failed.","triggerScenarios":"A registered Events.Listener (via org.apache.iceberg.events.Events) throws during a commit callback, or updateEvent()/metrics construction fails inside notifyListeners during commit().","commonSituations":"Custom listener implementations with bugs (NPEs, downstream HTTP calls failing); listeners that do network reporting to monitoring systems that are down; listener code incompatible with the event summary shape.","solutions":["Inspect the attached stack trace to find which listener threw.","Fix or wrap the faulty listener's onCommit handler so it does not throw.","Guard external calls inside listeners (timeouts, retries) so monitoring outages don't produce warnings on every commit.","If the listener is unnecessary, deregister it."],"exampleFix":"// before\nEvents.listeners().add(listener -> { metricsClient.post(listener); }); // throws on outage\n// after\nEvents.listeners().add(listener -> {\n  try { metricsClient.post(listener); } catch (Exception e) { log.warn(\"metrics post failed\", e); }\n});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  table.newAppend().appendFile(file).commit();\n} catch (Throwable t) {\n  LOG.warn(\"commit succeeded but event notification failed; verify listeners\", t);\n}","preventionTips":["Keep listener implementations exception-free with internal try/catch","Add timeouts/retries to any external calls made inside listeners","Test listeners against the event/report API version in use","Deregister listeners that are not needed"],"tags":["events","listeners","commit"],"backgroundTag":"http-request-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}