apache/seatunnel · error · SeaTunnelProtobufFormatException
DESCRIPTOR_CONVERT_FAILED
DESCRIPTOR_CONVERT_FAILED
Error message
Protoc compile error, exit code: %s
What it means
Thrown by CompileDescriptor.compileProtoToDescriptor when invoking the external 'protoc' binary to compile a .proto file into a descriptor set and protoc exits with a non-zero status. The exit code is included in the message. This happens lazily when the target descriptor path is needed.
Solutions
- Run the same protoc command manually on the node to see protoc's real stderr (only the exit code is logged here)
- Install/upgrade protoc and ensure it is on PATH or configure the protoc executable path
- Fix proto syntax errors and add missing imports with --proto_path/-I entries covering all imported files
- Verify the proto file's parent directory is the correct proto_path root for its import statements
Example fix
// before (shell diagnosis) protoc --proto_path=/tmp/protos --descriptor_set_out=/tmp/out.desc /tmp/protos/user.proto // e.g. "user.proto:4:1: File 'google/protobuf/timestamp.proto' was not found" // after protoc -I/usr/include -I/tmp/protos --proto_path=/tmp/protos --descriptor_set_out=/tmp/out.desc /tmp/protos/user.proto
Defensive patterns
Strategy: validation
Validate before calling
protoc --proto_path=<dir> --descriptor_set_out=/tmp/test.desc <file>.proto && echo OK || echo "protoc failed: $?"
Type guard
boolean protocAvailable() throws IOException, InterruptedException {
Process p = new ProcessBuilder("protoc", "--version").start();
return p.waitFor() == 0;
} Try / catch
try {
Path desc = compileDescriptor.targetDescPath(protoDir, protoFile);
} catch (SeaTunnelProtobufFormatException e) {
log.error("protoc failed (exit code in message). Run protoc manually for stderr.", e);
throw e;
} Prevention
- Install protoc and verify with 'protoc --version' on every node
- Run protoc manually once on your .proto files in CI before deploying
- Include all imported well-known types via -I/--proto_path entries
- Pin a protoc version compatible with your generated descriptors
When it happens
Trigger: Calling targetDescPath/compileProtoToDescriptor where the generated protoc command ('protoc --proto_path=... --descriptor_set_out=... file.proto') returns non-zero — protoc missing/unexecutable, .proto syntax errors, unresolved imports, or a wrong proto_path.
Common situations: protoc not installed or wrong version on the node; .proto references imports (e.g. google/protobuf/*.proto) not on the include path; proto_path pointing at the wrong parent directory; syntax errors after editing the proto.
Related errors
- Protobuf message not recognized at candidate offset
- SeaTunnel avro format is not supported for this data type
- UNSUPPORTED_DATA_TYPE
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/083ae8db6edb145b.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-formats/seatunnel-format-protobuf/src/main/java/org/apache/seatunnel/format/protobuf/CompileDescriptor.java:87
FileUtils.writeStringToFile(protoFile.getPath(), protoContent);
return protoFile;
}
private static String compileProtoToDescriptor(File tmpDir, File protoFile)
throws IOException, InterruptedException {
String targetDesc = tmpDir + "/.desc";
new File(targetDesc).deleteOnExit();
int exitCode =
Protoc.runProtoc(
new String[] {
"--proto_path=" + protoFile.getParent(),
"--descriptor_set_out=" + targetDesc,
protoFile.getPath()
});
if (exitCode != 0) {
throw new SeaTunnelProtobufFormatException(
ProtobufFormatErrorCode.DESCRIPTOR_CONVERT_FAILED,
"Protoc compile error, exit code: " + exitCode);
}
return targetDesc;
}
private static Descriptors.FileDescriptor[] buildFileDescriptors(
DescriptorProtos.FileDescriptorSet descriptorSet)
throws Descriptors.DescriptorValidationException {
List<DescriptorProtos.FileDescriptorProto> fileDescriptors = descriptorSet.getFileList();
Descriptors.FileDescriptor[] descriptorsArray =
new Descriptors.FileDescriptor[fileDescriptors.size()];
for (int i = 0; i < fileDescriptors.size(); i++) {
descriptorsArray[i] =
Descriptors.FileDescriptor.buildFrom(
fileDescriptors.get(i), new Descriptors.FileDescriptor[] {});
}
return descriptorsArray;View on GitHub (pinned to cf67b549a7)