{"record":{"id":"083ae8db6edb145b","repo":"apache/seatunnel","slug":"descriptor-convert-failed","errorCode":"DESCRIPTOR_CONVERT_FAILED","errorMessage":"Protoc compile error, exit code: %s","messagePattern":"Protoc compile error, exit code: (.+?)","errorType":"error_code","errorClass":"SeaTunnelProtobufFormatException","httpStatus":null,"severity":"error","filePath":"seatunnel-formats/seatunnel-format-protobuf/src/main/java/org/apache/seatunnel/format/protobuf/CompileDescriptor.java","lineNumber":87,"sourceCode":"        FileUtils.writeStringToFile(protoFile.getPath(), protoContent);\n        return protoFile;\n    }\n\n    private static String compileProtoToDescriptor(File tmpDir, File protoFile)\n            throws IOException, InterruptedException {\n        String targetDesc = tmpDir + \"/.desc\";\n        new File(targetDesc).deleteOnExit();\n\n        int exitCode =\n                Protoc.runProtoc(\n                        new String[] {\n                            \"--proto_path=\" + protoFile.getParent(),\n                            \"--descriptor_set_out=\" + targetDesc,\n                            protoFile.getPath()\n                        });\n\n        if (exitCode != 0) {\n            throw new SeaTunnelProtobufFormatException(\n                    ProtobufFormatErrorCode.DESCRIPTOR_CONVERT_FAILED,\n                    \"Protoc compile error, exit code: \" + exitCode);\n        }\n        return targetDesc;\n    }\n\n    private static Descriptors.FileDescriptor[] buildFileDescriptors(\n            DescriptorProtos.FileDescriptorSet descriptorSet)\n            throws Descriptors.DescriptorValidationException {\n        List<DescriptorProtos.FileDescriptorProto> fileDescriptors = descriptorSet.getFileList();\n        Descriptors.FileDescriptor[] descriptorsArray =\n                new Descriptors.FileDescriptor[fileDescriptors.size()];\n        for (int i = 0; i < fileDescriptors.size(); i++) {\n            descriptorsArray[i] =\n                    Descriptors.FileDescriptor.buildFrom(\n                            fileDescriptors.get(i), new Descriptors.FileDescriptor[] {});\n        }\n        return descriptorsArray;","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-formats/seatunnel-format-protobuf/src/main/java/org/apache/seatunnel/format/protobuf/CompileDescriptor.java#L69-L105","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (shell diagnosis)\nprotoc --proto_path=/tmp/protos --descriptor_set_out=/tmp/out.desc /tmp/protos/user.proto\n// e.g. \"user.proto:4:1: File 'google/protobuf/timestamp.proto' was not found\"\n\n// after\nprotoc -I/usr/include -I/tmp/protos --proto_path=/tmp/protos --descriptor_set_out=/tmp/out.desc /tmp/protos/user.proto","handlingStrategy":"validation","validationCode":"protoc --proto_path=<dir> --descriptor_set_out=/tmp/test.desc <file>.proto && echo OK || echo \"protoc failed: $?\"","typeGuard":"boolean protocAvailable() throws IOException, InterruptedException {\n    Process p = new ProcessBuilder(\"protoc\", \"--version\").start();\n    return p.waitFor() == 0;\n}","tryCatchPattern":"try {\n    Path desc = compileDescriptor.targetDescPath(protoDir, protoFile);\n} catch (SeaTunnelProtobufFormatException e) {\n    log.error(\"protoc failed (exit code in message). Run protoc manually for stderr.\", e);\n    throw e;\n}","preventionTips":["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"],"tags":["protobuf","protoc","compilation","external-process"],"backgroundTag":"command-not-found","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}