apache/flink · error · IOException

Unknown "op_type" value "%s". The Ogg JSON message is '%s'

Error message

Unknown "op_type" value "%s". The Ogg JSON message is '%s'

What it means

The 'op_type' field of an Ogg JSON message was not one of the recognized values ('I' insert, 'U' update, 'D' delete as OP_CREATE/OP_UPDATE/OP_DELETE). With 'ogg-json.ignore-parse-errors' = false the deserializer throws IOException including the offending op_type and the raw message; with it true the event is debug-logged and skipped.

Source

Thrown at flink-formats/flink-json/src/main/java/org/apache/flink/formats/json/ogg/OggJsonDeserializationSchema.java:201

            } else if (OP_UPDATE.equals(op)) {
                if (before == null) {
                    throw new IllegalStateException(
                            String.format(REPLICA_IDENTITY_EXCEPTION, "UPDATE"));
                }
                before.setRowKind(RowKind.UPDATE_BEFORE);
                after.setRowKind(RowKind.UPDATE_AFTER);
                genericRowDataList.add(emitRow(row, before));
                genericRowDataList.add(emitRow(row, after));
            } else if (OP_DELETE.equals(op)) {
                if (before == null) {
                    throw new IllegalStateException(
                            String.format(REPLICA_IDENTITY_EXCEPTION, "DELETE"));
                }
                before.setRowKind(RowKind.DELETE);
                genericRowDataList.add(emitRow(row, before));
            } else {
                if (!ignoreParseErrors) {
                    throw new IOException(
                            format(
                                    "Unknown \"op_type\" value \"%s\". The Ogg JSON message is '%s'",
                                    op, new String(message)));
                }
                if (LOG.isDebugEnabled()) {
                    LOG.debug(
                            "Unknown \"op_type\" value '{}'. The Ogg JSON message is '{}'.",
                            op,
                            new String(message));
                }
            }
        } catch (Throwable t) {
            // a big try catch to protect the processing.
            if (!ignoreParseErrors) {
                throw new IOException(
                        format("Corrupt Ogg JSON message '%s'.", new String(message)), t);
            }
            if (LOG.isDebugEnabled()) {

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Set 'ogg-json.ignore-parse-errors' = true on the source table to skip unsupported event kinds.
  2. Configure the Ogg/GoldenGate extract or Kafka routing to publish only row-change (DML) events to the consumed topic.
  3. Verify with a console consumer which op_type values actually appear and align the format expectation.

Example fix

-- before
'format' = 'ogg-json'
-- after
'format' = 'ogg-json',
'ogg-json.ignore-parse-errors' = 'true'
Defensive patterns

Strategy: try-catch

Validate before calling

JsonNode n = MAPPER.readTree(message);
String op = n.path("op_type").asText("");
if (!("I".equals(op) || "U".equals(op) || "D".equals(op))) return; // skip non-DML

Try / catch

try { deserializer.deserialize(message, collector); } catch (IOException e) { skipped.inc(); log.warn("Unsupported Ogg op_type in {}", new String(message)); }

Prevention

When it happens

Trigger: Ogg GoldenGate messages with op_type values outside I/U/D — e.g. DDL events, transaction markers, or truncate operations — arriving on a topic read by an ogg-json table source.

Common situations: Capturing Ogg topics that include DDL/transaction metadata records; producer-side format changes or custom op_type encodings; truncated/corrupt single messages.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/ff67f45f017039b8. Report an issue: GitHub.