{"record":{"id":"8e9bcf10397687ef","repo":"grpc/grpc-java","slug":"cannot-load-epollserversocketchannel","errorCode":null,"errorMessage":"Cannot load EpollServerSocketChannel","messagePattern":"Cannot load EpollServerSocketChannel","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"netty/src/main/java/io/grpc/netty/Utils.java","lineNumber":437,"sourceCode":"          .forName(\"io.netty.channel.epoll.EpollEventLoopGroup\").asSubclass(EventLoopGroup.class)\n          .getConstructor(Integer.TYPE, ThreadFactory.class);\n    } catch (ClassNotFoundException e) {\n      throw new RuntimeException(\"Cannot load EpollEventLoopGroup\", e);\n    } catch (NoSuchMethodException e) {\n      throw new RuntimeException(\"EpollEventLoopGroup constructor not found\", e);\n    }\n  }\n\n  // Must call when epoll is available\n  private static Class<? extends ServerChannel> epollServerChannelType() {\n    try {\n      Class<? extends ServerChannel> serverSocketChannel =\n          Class\n              .forName(\"io.netty.channel.epoll.EpollServerSocketChannel\")\n              .asSubclass(ServerChannel.class);\n      return serverSocketChannel;\n    } catch (ClassNotFoundException e) {\n      throw new RuntimeException(\"Cannot load EpollServerSocketChannel\", e);\n    }\n  }\n\n  private static EventLoopGroup createEpollEventLoopGroup(\n      int parallelism,\n      ThreadFactory threadFactory) {\n    checkState(EPOLL_EVENT_LOOP_GROUP_CONSTRUCTOR != null, \"Epoll is not available\");\n\n    try {\n      return EPOLL_EVENT_LOOP_GROUP_CONSTRUCTOR\n          .newInstance(parallelism, threadFactory);\n    } catch (Exception e) {\n      throw new RuntimeException(\"Cannot create Epoll EventLoopGroup\", e);\n    }\n  }\n\n  private static ChannelFactory<ServerChannel> nioServerChannelFactory() {\n    return new ChannelFactory<ServerChannel>() {","sourceCodeStart":419,"sourceCodeEnd":455,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/netty/src/main/java/io/grpc/netty/Utils.java#L419-L455","documentation":"gRPC-netty loads io.netty.channel.epoll.EpollServerSocketChannel reflectively when configuring an epoll-based server. This RuntimeException wraps the ClassNotFoundException raised when the epoll transport classes are absent from the classpath. It is thrown only after the code has already assumed epoll is available, so it signals a missing/mispackaged epoll dependency.","triggerScenarios":"Starting a gRPC server on the epoll transport, which calls Utils.epollServerChannelType() to resolve the server channel class, while io.netty:netty-transport-native-epoll is missing from the runtime classpath.","commonSituations":"Deploying gRPC servers to Linux with epoll transport enabled (explicitly or via default detection) but the slim Docker image or shaded jar omitted netty-transport-native-epoll; Netty version mismatch removing io.netty.channel.epoll classes; non-Linux deployment accidentally taking the epoll path.","solutions":["Add io.netty:netty-transport-native-epoll with the matching linux classifier and Netty version to the server's runtime classpath","Verify the packaged artifact (jar/image) contains io/netty/channel/epoll/EpollServerSocketChannel and the native epoll .so","Use a consistent Netty version (netty-bom) so grpc-netty's reflective lookups resolve","Only enable the epoll transport on Linux; otherwise rely on the default NIO transport"],"exampleFix":"// before (build.gradle)\nimplementation 'io.grpc:grpc-netty-shaded:1.x' // or grpc-netty without epoll natives\n\n// after\nimplementation 'io.grpc:grpc-netty:1.x'\nruntimeOnly 'io.netty:netty-transport-native-epoll:4.1.100.Final:linux-x86_64'\nruntimeOnly 'io.netty:netty-transport-native-unix-common:4.1.100.Final:linux-x86_64'","handlingStrategy":"fallback","validationCode":"static boolean epollServerTransportReady() {\n  try {\n    Class.forName(\"io.netty.channel.epoll.EpollServerSocketChannel\");\n    return true;\n  } catch (ClassNotFoundException e) {\n    return false;\n  }\n}","typeGuard":"static Class<? extends io.netty.channel.ServerChannel> serverChannelTypeOrNio() {\n  try {\n    return io.grpc.netty.Utils.EPOLL_SERVER_CHANNEL_TYPE;\n  } catch (Throwable t) {\n    return io.netty.channel.socket.nio.NioServerSocketChannel.class;\n  }\n}","tryCatchPattern":"try {\n  return NettyServerBuilder.forPort(port)\n      .channelType(io.grpc.netty.Utils.EPOLL_SERVER_CHANNEL_TYPE)\n      .build();\n} catch (RuntimeException e) {\n  if (e.getCause() instanceof ClassNotFoundException) {\n    return NettyServerBuilder.forPort(port) // default NIO transport\n        .build();\n  }\n  throw e;\n}","preventionTips":["Add netty-transport-native-epoll runtime dependency for Linux server deployments","Confirm the deployment image includes both epoll classes and the native .so","Let gRPC auto-detect transport rather than forcing epoll","Gate epoll usage on Linux OS check at startup","Keep Netty versions aligned via netty-bom in dependencyManagement"],"tags":["netty","grpc","server","classpath","epoll"],"backgroundTag":"class-not-found","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}