apache/flink · error · UnsupportedOperationException

Protocol Buffers editions syntax is not supported

Error message

Protocol Buffers editions syntax is not supported

What it means

The patched protobuf-to-parquet writer detects the file's syntax via string comparison and rejects 'editions' syntax. Protobuf editions change semantics in ways this writer's proto2/proto3 field-presence logic cannot handle, so it throws UnsupportedOperationException.

Source

Thrown at flink-formats/flink-parquet/src/main/java/org/apache/flink/formats/parquet/protobuf/PatchedProtoWriteSupport.java:481

        /** Used for writing nonrepeated (optional, required) fields. */
        @Override
        final void writeField(Object value) {
            recordConsumer.startField(fieldName, index);
            writeRawValue(value);
            recordConsumer.endField(fieldName, index);
        }

        private void writeAllFields(MessageOrBuilder pb) {
            Descriptor messageDescriptor = pb.getDescriptorForType();
            // ============================================================================
            // BEGIN PATCH: Replace enum-based syntax detection with string-based approach
            // ============================================================================
            String syntax = messageDescriptor.getFile().toProto().getSyntax();

            // Check for editions syntax (not supported)
            if ("editions".equals(syntax)) {
                throw new UnsupportedOperationException(
                        "Protocol Buffers editions syntax is not supported");
            }

            // proto2 uses empty string or "proto2", proto3 uses "proto3"
            boolean isProto2 = syntax.isEmpty() || "proto2".equals(syntax);

            if (isProto2) {
                // ============================================================================
                // END PATCH
                // ============================================================================
                // Returns changed fields with values. Map is ordered by id.
                Map<FieldDescriptor, Object> changedPbFields = pb.getAllFields();

                for (Map.Entry<FieldDescriptor, Object> entry : changedPbFields.entrySet()) {
                    FieldDescriptor fieldDescriptor = entry.getKey();

                    if (fieldDescriptor.isExtension()) {
                        // Field index of an extension field might overlap with a base field.

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Convert the .proto back to syntax = "proto3" (or proto2) and regenerate the Java classes
  2. Keep a separate proto2/proto3 build of the message classes for the parquet sink path
  3. Watch upstream parquet-proto support for editions and upgrade once supported

Example fix

// before
// edition = "2023";
// message User { string name = 1; }

// after
syntax = "proto3";
message User { string name = 1; }
Defensive patterns

Strategy: type-guard

Type guard

boolean isEditionsSyntax(MessageOrBuilder msg) {
  return "editions".equals(msg.getDescriptorForType().getFile().toProto().getSyntax());
}

Try / catch

try { writer.write(msg); } catch (UnsupportedOperationException e) { if (e.getMessage().contains("editions")) { // regenerate protos with proto3 syntax and retry } throw e; }

Prevention

When it happens

Trigger: Writing a Message whose .proto file declares 'edition = "2023"' (or later) instead of syntax = "proto2"/"proto3".

Common situations: Upgrading a proto file to editions 2023, or depending on a third-party .proto that uses editions, then feeding those messages to ProtoParquetOutputFormat.

Related errors


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