{"record":{"id":"79be422bebcd07d9","repo":"quarkusio/quarkus","slug":"failed-to-generate-java-classes-from-proto-files","errorCode":null,"errorMessage":"Failed to generate Java classes from proto files: %s to %s with command %s","messagePattern":"Failed to generate Java classes from proto files: (.+?) to (.+?) with command (.+?)","errorType":"exception","errorClass":"CodeGenException","httpStatus":null,"severity":"error","filePath":"extensions/grpc/codegen/src/main/java/io/quarkus/grpc/codegen/GrpcCodeGen.java","lineNumber":210,"sourceCode":"                        for (int i = 1; i < command.size(); i++) {\n                            writer.println(command.get(i));\n                        }\n                    }\n\n                    command = new ArrayList<>(List.of(command.get(0), \"@\" + argFile.getAbsolutePath()));\n                }\n                log.debugf(\"Executing command: %s\", String.join(\" \", command));\n                try {\n                    ProcessBuilder<Void> pb = ProcessBuilder.newBuilder(command.get(0),\n                            command.subList(1, command.size()));\n                    // Tune the environment for compatibility with Java >24 without triggering warnings\n                    pb.modifyEnvironment(GrpcCodeGen::invocationEnvironmentTuning);\n                    // Set up a custom output handler to highlight only relevant errors\n                    pb.output().consumeLinesWith(100, this::outputConsumer);\n                    pb.error().consumeLinesWith(100, this::outputConsumer).logOnSuccess(false);\n                    pb.run();\n                } catch (Exception e) {\n                    throw new CodeGenException(\"Failed to generate Java classes from proto files: %s to %s with command %s\"\n                            .formatted(protoFiles, outDir.toAbsolutePath(), String.join(\" \", command)), e);\n                }\n                postprocessing(context, outDir);\n                log.info(\"Successfully finished generating and post-processing sources from proto files\");\n\n                return true;\n            }\n        } catch (IOException e) {\n            throw new CodeGenException(\n                    \"Failed to generate java files from proto file in \" + inputDir.toAbsolutePath(), e);\n        }\n\n        return false;\n    }\n\n    private static void invocationEnvironmentTuning(final Map<String, String> environment) {\n        //This specific environment variable is being picked up by the JVMs spawned by protoc:\n        final String key = \"JDK_JAVA_OPTIONS\";","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/codegen/GrpcCodeGen.java#L192-L228","documentation":"GrpcCodeGen.trigger invokes the protoc binary via the protobuf plugin's ProcessBuilder helper to generate Java sources from .proto files. Any exception from the protoc invocation is wrapped in a CodeGenException that names the proto files, output directory, and exact command line — this is the canonical 'protoc failed' build error in Quarkus gRPC.","triggerScenarios":"Building a Quarkus app where protoc fails: missing/incompatible protoc binary for the platform, invalid .proto syntax, proto files importing unavailable files, or protoc exiting with a non-zero code.","commonSituations":"Unsupported OS/arch (no prebuilt protoc binary); proto files with syntax errors or missing imports; permission issues on the output directory; corporate proxies blocking protoc artifact download in older versions.","solutions":["Read the highlighted protoc output above the exception (the outputConsumer prints relevant errors) for the exact .proto error line","Fix the reported .proto syntax/import errors in src/main/proto","Verify the output directory is writable and the platform has a compatible protoc binary; clean and rebuild (./mvnw clean install)"],"exampleFix":"// before\n// src/main/proto/item.proto\nsyntax = \"proto3\";\nmessage Item { int32 id = 1; string name = ; } // syntax error\n// after\nsyntax = \"proto3\";\nmessage Item { int32 id = 1; string name = 2; }","handlingStrategy":"try-catch","validationCode":"// Pre-check proto files before building:\nfor (f in src/main/proto/*.proto) {\n    assert f.text.startsWith('syntax'); // every proto must declare syntax\n}\nassert file('src/main/proto').canRead()\nassert file('target/generated-sources').parentFile.canWrite()","typeGuard":null,"tryCatchPattern":"try {\n    mvn clean install;\n} catch (CodeGenException e) {\n    // message names protos, out dir, and command; read the highlighted protoc lines above\n    System.err.println(e.getMessage());\n    Throwable root = e.getCause();\n    while (root != null) { System.err.println(root); root = root.getCause(); }\n}","preventionTips":["Validate .proto files with protoc locally (protoc --proto_path=src/main/proto --descriptor_set_out=/dev/null ...) before building","Keep protos syntactically correct and imports available in src/main/proto","Ensure a compatible protoc binary exists for your OS/arch and that output dirs are writable"],"tags":["grpc","codegen","protoc","build"],"backgroundTag":"protoc-generation-failed","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}