{"record":{"id":"dded61950af6c259","repo":"provectus/kafka-ui","slug":"proto-files-directory-not-readable","errorCode":null,"errorMessage":"proto files directory not readable","messagePattern":"proto files directory not readable","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"error","filePath":"kafka-ui-api/src/main/java/com/provectus/kafka/ui/serdes/builtin/ProtobufFileSerde.java","lineNumber":315,"sourceCode":"    }\n\n    private static void addProtobufSchemas(Map<Descriptor, Path> descriptorPaths,\n                                           Map<Path, ProtobufSchema> protobufSchemas,\n                                           Map<String, String> messageNamesByTopic) {\n      messageNamesByTopic.values().stream()\n          .map(msgName -> getDescriptorAndPath(protobufSchemas, msgName))\n          .forEach(entry -> descriptorPaths.put(entry.getKey(), entry.getValue()));\n    }\n  }\n\n  static class ProtoSchemaLoader {\n\n    private final Path baseLocation;\n\n    ProtoSchemaLoader(String baseLocationStr) {\n      this.baseLocation = Path.of(baseLocationStr);\n      if (!Files.isReadable(baseLocation)) {\n        throw new ValidationException(\"proto files directory not readable\");\n      }\n    }\n\n    List<ProtoFile> load() {\n      Map<String, ProtoFile> knownTypes = knownProtoFiles();\n\n      Map<String, ProtoFile> filesByLocations = new HashMap<>();\n      filesByLocations.putAll(knownTypes);\n      filesByLocations.putAll(loadFilesWithLocations());\n\n      Linker linker = new Linker(\n          createFilesLoader(filesByLocations),\n          new ErrorCollector(),\n          true,\n          true\n      );\n      var schema = linker.link(filesByLocations.values());\n      linker.getErrors().throwIfNonEmpty();","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/provectus/kafka-ui/blob/83b5a60cc08501b570a0c4d0b4cdfceb1b88d6b7/kafka-ui-api/src/main/java/com/provectus/kafka/ui/serdes/builtin/ProtobufFileSerde.java#L297-L333","documentation":"ProtobufFileSerde's nested ProtoSchemaLoader resolves the configured base directory for .proto files and immediately checks readability. If the path does not exist or the kafka-ui process lacks read permission, ValidationException('proto files directory not readable') is thrown at configuration time.","triggerScenarios":"Constructing ProtoSchemaLoader with a baseLocationStr whose Path is unreadable — nonexistent directory, wrong mount, or file-system permissions denying the process access.","commonSituations":"Descriptor paths mounted in a container but the volume not mounted in the kafka-ui pod; directory owned by another user; typo in the path or relative path resolved against an unexpected working directory.","solutions":["Fix the configured directory path to point at an existing directory","chmod/chown the directory so the kafka-ui process user can read it, or run the container with the right volume mount","Verify inside the container (ls on the path) that the directory is visible and readable"],"exampleFix":"// before\nserde:\n  protobufFileSerde:\n    descriptorPaths: /proto  # not mounted\n// after\nserde:\n  protobufFileSerde:\n    descriptorPaths: /etc/kafka-ui/proto  # exists & readable\n# shell: chmod o+rx /etc/kafka-ui/proto","handlingStrategy":"validation","validationCode":"Path dir = Path.of(baseLocationStr); if (!Files.isDirectory(dir) || !Files.isReadable(dir)) throw new IllegalArgumentException(\"proto dir missing/unreadable: \" + dir);","typeGuard":"boolean isReadableDir(String p) { Path d = Path.of(p); return Files.isDirectory(d) && Files.isReadable(d); }","tryCatchPattern":"try { new ProtoSchemaLoader(path); } catch (ValidationException e) { alert(\"proto dir unreadable: \" + path); }","preventionTips":["Mount proto directories as read-only volumes and verify in the container image","Use absolute paths in descriptorPaths","Add a startup health check that stats the proto directory"],"tags":["filesystem","permissions","protobuf"],"backgroundTag":"permission-denied","analyzedSha":"83b5a60cc08501b570a0c4d0b4cdfceb1b88d6b7","analyzedAt":"2026-09-08T04:35:39.002Z","contentChangedAt":"2026-09-08T04:35:39.002Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}