{"record":{"id":"f40a73444494d0c3","repo":"apache/flink","slug":"unsupported-operation-s-for-row-kind","errorCode":null,"errorMessage":"Unsupported operation '%s' for row kind.","messagePattern":"Unsupported operation '(.+?)' for row kind\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink-formats/flink-avro-confluent-registry/src/main/java/org/apache/flink/formats/avro/registry/confluent/debezium/DebeziumAvroSerializationSchema.java","lineNumber":123,"sourceCode":"\n    @Override\n    public byte[] serialize(RowData rowData) {\n        try {\n            switch (rowData.getRowKind()) {\n                case INSERT:\n                case UPDATE_AFTER:\n                    outputReuse.setField(0, null);\n                    outputReuse.setField(1, rowData);\n                    outputReuse.setField(2, OP_INSERT);\n                    return avroSerializer.serialize(outputReuse);\n                case UPDATE_BEFORE:\n                case DELETE:\n                    outputReuse.setField(0, rowData);\n                    outputReuse.setField(1, null);\n                    outputReuse.setField(2, OP_DELETE);\n                    return avroSerializer.serialize(outputReuse);\n                default:\n                    throw new UnsupportedOperationException(\n                            format(\n                                    \"Unsupported operation '%s' for row kind.\",\n                                    rowData.getRowKind()));\n            }\n        } catch (Throwable t) {\n            throw new RuntimeException(format(\"Could not serialize row '%s'.\", rowData), t);\n        }\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) {\n            return true;\n        }\n        if (o == null || getClass() != o.getClass()) {\n            return false;\n        }\n        DebeziumAvroSerializationSchema that = (DebeziumAvroSerializationSchema) o;","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-formats/flink-avro-confluent-registry/src/main/java/org/apache/flink/formats/avro/registry/confluent/debezium/DebeziumAvroSerializationSchema.java#L105-L141","documentation":"Thrown by DebeziumAvroSerializationSchema.serialize() when the RowData's RowKind is not one of the four handled cases (INSERT, UPDATE_AFTER, UPDATE_BEFORE, DELETE). RowKind only defines those four values in stock Flink, so this branch is effectively defensive: it fires when a custom RowKind short-string was injected or a future Flink version adds kinds the serializer has not been taught.","triggerScenarios":"Constructing RowData with RowKind.of(short) custom values in a user function feeding this sink; forwarding rows from a source that invents new kinds; running a mismatched flink-avro-confluent-registry jar (older serializer) against a newer runtime with extended RowKinds.","commonSituations":"Custom connectors or UDFs labeling rows with bespoke kinds; version skew between shaded format jar and runtime; test fixtures building RowKind by string.","solutions":["Normalize RowKind upstream: map any custom kind to one of +I/-U/+U/-D before the sink (e.g. treat custom upserts as UPDATE_AFTER/INSERT).","Align versions: use the flink-avro-confluent-registry artifact built for your Flink runtime version.","Audit any code calling RowKind.of(...) or constructing GenericRowData with kinds to confirm they only use the standard four."],"exampleFix":"// before\nrowData.setRowKind(RowKind.of(\"X\")); // custom kind -> hits default branch\n\n// after\nrowData.setRowKind(RowKind.UPDATE_AFTER);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"private static final Set<String> SUPPORTED_KINDS =\n    Set.of(\"+I\", \"-U\", \"+U\", \"-D\");\nstatic boolean isSerializableKind(RowKind k) {\n    return SUPPORTED_KINDS.contains(k.shortString());\n}","tryCatchPattern":"catch (RuntimeException e) { if (e.getCause() instanceof UnsupportedOperationException) { /* normalize row kind upstream and re-emit, or drop row to DLQ */ } else throw e; }","preventionTips":["Only use the four standard RowKind constants","Map custom upsert semantics to UPDATE_AFTER/UPDATE_BEFORE at the source","Pin the format jar version to the runtime version"],"tags":["debezium","avro","row-kind","serialization"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}