apache/flink · error · PbCodegenException
Illegal type for protobuf enum, only char/vachar/int/bigint
Error message
Illegal type for protobuf enum, only char/vachar/int/bigint is supported
What it means
When a proto field is an ENUM, the deserializer only accepts Flink CHAR/VARCHAR (stringified) or TINYINT/SMALLINT/INTEGER/BIGINT (numeric getNumber()). Any other type root for that column (e.g. BOOLEAN, DOUBLE, DECIMAL) throws this PbCodegenException at codegen time. The message text 'vachar' is a known typo for varchar.
Source
Thrown at flink-formats/flink-protobuf/src/main/java/org/apache/flink/formats/protobuf/deserialize/PbCodegenSimpleDeserializer.java:76
+ " = BinaryStringData.fromString("
+ pbObjectCode
+ ".toString())");
break;
case ENUM:
if (logicalType.getTypeRoot() == LogicalTypeRoot.CHAR
|| logicalType.getTypeRoot() == LogicalTypeRoot.VARCHAR) {
appender.appendLine(
resultVar
+ " = BinaryStringData.fromString("
+ pbObjectCode
+ ".toString())");
} else if (logicalType.getTypeRoot() == LogicalTypeRoot.TINYINT
|| logicalType.getTypeRoot() == LogicalTypeRoot.SMALLINT
|| logicalType.getTypeRoot() == LogicalTypeRoot.INTEGER
|| logicalType.getTypeRoot() == LogicalTypeRoot.BIGINT) {
appender.appendLine(resultVar + " = " + pbObjectCode + ".getNumber()");
} else {
throw new PbCodegenException(
"Illegal type for protobuf enum, only char/vachar/int/bigint is supported");
}
break;
default:
throw new PbCodegenException(
"Unsupported protobuf simple type: " + fd.getJavaType());
}
return appender.code();
}
}
View on GitHub (pinned to 2f3c205e92)
Solutions
- Change the offending column to VARCHAR (stores enum name) or INT/BIGINT (stores enum number) so it matches the proto enum field.
- If you need DECIMAL, map to a proto int64/int32 field instead of enum in the .proto, or preprocess the value upstream.
- Validate schema against the descriptor with PbSchemaValidationUtils.validatePbStruct before job submission.
Example fix
-- before (proto field 'status' is enum) status DECIMAL(10,0), -- after status INT, -- or VARCHAR
Defensive patterns
Strategy: validation
Validate before calling
FieldDescriptor fd = descriptor.findFieldByName(col);
if (fd != null && fd.getJavaType() == JavaType.ENUM) {
LogicalTypeRoot r = colType.getTypeRoot();
boolean ok = r == LogicalTypeRoot.CHAR || r == LogicalTypeRoot.VARCHAR
|| r == LogicalTypeRoot.TINYINT || r == LogicalTypeRoot.SMALLINT
|| r == LogicalTypeRoot.INTEGER || r == LogicalTypeRoot.BIGINT;
if (!ok) throw new IllegalArgumentException("Enum field " + col + " must be string or integer");
} Prevention
- Adopt a convention: proto enum <-> Flink INT (number) or VARCHAR (name); document it in the schema repo.
- Run PbSchemaValidationUtils.validatePbStruct on new/changed DDLs in CI.
When it happens
Trigger: DDL maps an enum proto field to a non-string/non-integer column, e.g. status DECIMAL(10,0) while the proto defines status as enum Status.
Common situations: Inferring the table schema from a data lake/AVRO-like source where enums became strings or decimals, then pointing the same schema at a protobuf message class; evolving the proto field from int to enum without updating the DDL.
Related errors
- Do not support flink type:
- Unsupported data type in schema:
- Expected two fields for the map (key/value), but got: {}
- Unknown type with descriptor "{}" and type "{}."
- Unsupported protobuf simple type:
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/b7aaff2df6454ffe.
Report an issue: GitHub.