{"record":{"id":"5537badd1e506b32","repo":"grpc/grpc-java","slug":"cannot-load-epolleventloopgroup","errorCode":null,"errorMessage":"Cannot load EpollEventLoopGroup","messagePattern":"Cannot load EpollEventLoopGroup","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"netty/src/main/java/io/grpc/netty/Utils.java","lineNumber":422,"sourceCode":"  // Must call when epoll is available\n  private static Class<? extends Channel> epollDomainSocketChannelType() {\n    try {\n      Class<? extends Channel> channelType = Class\n          .forName(\"io.netty.channel.epoll.EpollDomainSocketChannel\").asSubclass(Channel.class);\n      return channelType;\n    } catch (ClassNotFoundException e) {\n      throw new RuntimeException(\"Cannot load EpollDomainSocketChannel\", e);\n    }\n  }\n\n  // Must call when epoll is available\n  private static Constructor<? extends EventLoopGroup> epollEventLoopGroupConstructor() {\n    try {\n      return Class\n          .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","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/netty/src/main/java/io/grpc/netty/Utils.java#L404-L440","documentation":"gRPC-netty reflectively loads io.netty.channel.epoll.EpollEventLoopGroup and looks up its (int, ThreadFactory) constructor. This RuntimeException wraps ClassNotFoundException, meaning the epoll transport classes are missing from the classpath at the moment the epoll event loop group is created.","triggerScenarios":"Creating the epoll event loop group via Utils.epollEventLoopGroupConstructor() when building an epoll-based channel/server (Utils.createEpollEventLoopGroup) while io.netty:netty-transport-native-epoll is not on the runtime classpath.","commonSituations":"Using EpollEventLoopGroupConfigured transport options (NettyServerBuilder/NettyChannelBuilder with epoll transport) on Linux where the native epoll dependency was not bundled; Netty version drift causing io.netty.channel.epoll.EpollEventLoopGroup to disappear from the jar set; shaded jars missing epoll classes.","solutions":["Add io.netty:netty-transport-native-epoll with a linux classifier matching your platform and Netty version","Verify with dependency:tree that only one consistent Netty version is present and it contains EpollEventLoopGroup","If epoll transport was configured explicitly (transport(...)/epoll option), remove that setting to fall back to the default NIO event loop group","Ensure the native epoll library (.so) is packaged — the classes alone are insufficient if the native binding is also stripped"],"exampleFix":"// before\nNettyServerBuilder.forPort(8080)\n    .transport(NettyServerBuilder.EPOLL) // requires epoll on classpath\n    .build();\n\n// after — add to build:\n// implementation 'io.netty:netty-transport-native-epoll:4.1.x:linux-x86_64'\nNettyServerBuilder.forPort(8080)\n    .transport(NettyServerBuilder.EPOLL)\n    .build();","handlingStrategy":"fallback","validationCode":"static boolean epollEventLoopAvailable() {\n  try {\n    Class.forName(\"io.netty.channel.epoll.EpollEventLoopGroup\")\n        .getConstructor(Integer.TYPE, ThreadFactory.class);\n    return true;\n  } catch (ClassNotFoundException | NoSuchMethodException e) {\n    return false;\n  }\n}","typeGuard":"static boolean canCreateEpollEventLoopGroup() {\n  try {\n    Class<?> c = Class.forName(\"io.netty.channel.epoll.EpollEventLoopGroup\");\n    return c.getConstructor(Integer.TYPE, ThreadFactory.class) != null;\n  } catch (Throwable t) {\n    return false;\n  }\n}","tryCatchPattern":"try {\n  builder.eventLoopGroup(io.grpc.netty.Utils.createEpollEventLoopGroup(cores, factory));\n} catch (RuntimeException e) {\n  if (e.getCause() instanceof ClassNotFoundException) {\n    builder.eventLoopGroup(new NioEventLoopGroup(cores, factory));\n  } else {\n    throw e;\n  }\n}","preventionTips":["Include netty-transport-native-epoll (linux classifier) whenever epoll transport is configured","Verify the (int, ThreadFactory) constructor exists in your Netty version before reflecting","Pin Netty versions with netty-bom to avoid unexpected upgrades","Avoid hardcoding epoll event loop groups; rely on gRPC defaults where possible","Confirm native epoll .so is packaged alongside the classes"],"tags":["netty","grpc","eventloop","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"}