{"record":{"id":"a471cd0f9f4246e6","repo":"apache/iceberg","slug":"invalid-operator-event-type-eventclasscanonical","errorCode":null,"errorMessage":"Invalid operator event type: ${eventClassCanonicalName}","messagePattern":"Invalid operator event type: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/sink/shuffle/DataStatisticsCoordinator.java","lineNumber":322,"sourceCode":"    }\n  }\n\n  @Override\n  public void handleEventFromOperator(int subtask, int attemptNumber, OperatorEvent event) {\n    runInCoordinatorThread(\n        () -> {\n          LOG.debug(\n              \"Handling event from subtask {} (#{}) of {}: {}\",\n              subtask,\n              attemptNumber,\n              operatorName,\n              event);\n          if (event instanceof StatisticsEvent) {\n            handleDataStatisticRequest(subtask, ((StatisticsEvent) event));\n          } else if (event instanceof RequestGlobalStatisticsEvent) {\n            handleRequestGlobalStatisticsEvent(subtask, (RequestGlobalStatisticsEvent) event);\n          } else {\n            throw new IllegalArgumentException(\n                \"Invalid operator event type: \" + event.getClass().getCanonicalName());\n          }\n        },\n        String.format(\n            Locale.ROOT,\n            \"handling operator event %s from subtask %d (#%d)\",\n            event.getClass(),\n            subtask,\n            attemptNumber));\n  }\n\n  @Override\n  public void checkpointCoordinator(long checkpointId, CompletableFuture<byte[]> resultFuture) {\n    runInCoordinatorThread(\n        () -> {\n          LOG.debug(\n              \"Snapshotting data statistics coordinator {} for checkpoint {}\",\n              operatorName,","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/sink/shuffle/DataStatisticsCoordinator.java#L304-L340","documentation":"DataStatisticsCoordinator.handleEventFromOperator dispatches operator events from subtasks: StatisticsEvent for statistics requests and RequestGlobalStatisticsEvent for global statistics requests. Any other OperatorEvent type is rejected with IllegalArgumentException naming the event class, because this coordinator only understands its own two event types.","triggerScenarios":"An OperatorEvent arrives at the coordinator that is neither StatisticsEvent nor RequestGlobalStatisticsEvent — e.g. a custom event sent via OperatorEventSender to the coordinator, or a version-mismatched job sending a different event class to this endpoint.","commonSituations":"Mixing Iceberg versions in a job (old task code sending event types the new coordinator doesn't know), speculative-execution or failover artifacts delivering unexpected events, or user code sending custom operator events to the sink coordinator.","solutions":["Ensure all job nodes (JobManager and TaskManagers) run the same Iceberg/Flink connector version so event classes match","Check for custom code or framework features sending operator events to the Iceberg sink coordinator that it does not support","Restart the job from a clean state; stale events from a previous failed run can be delivered after restart","If reproducible with a single version, file an Iceberg issue with the event class name from the message"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!(event instanceof StatisticsEvent) && !(event instanceof RequestGlobalStatisticsEvent)) {\n  throw new IllegalArgumentException(\"Event not accepted by DataStatisticsCoordinator: \" + event.getClass().getCanonicalName());\n}","typeGuard":"static boolean isAcceptedOperatorEvent(OperatorEvent event) {\n  return event instanceof StatisticsEvent || event instanceof RequestGlobalStatisticsEvent;\n}","tryCatchPattern":null,"preventionTips":["Never send custom OperatorEvents to the Iceberg sink coordinator","Pin one connector version across JobManager and all TaskManagers","Fully cancel old jobs before starting replacements that share event channels"],"tags":["flink","operator-event","coordinator","version-mismatch"],"backgroundTag":"unexpected-response-shape","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}