{"record":{"id":"32d49fec5fdd9e75","repo":"grpc/grpc-java","slug":"cannot-load-epollsocketchannel","errorCode":null,"errorMessage":"Cannot load EpollSocketChannel","messagePattern":"Cannot load EpollSocketChannel","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"netty/src/main/java/io/grpc/netty/Utils.java","lineNumber":400,"sourceCode":"    try {\n      return (Throwable)\n          Class\n              .forName(\"io.netty.channel.epoll.Epoll\")\n              .getDeclaredMethod(\"unavailabilityCause\")\n              .invoke(null);\n    } catch (Exception e) {\n      return e;\n    }\n  }\n\n  // Must call when epoll is available\n  private static Class<? extends Channel> epollChannelType() {\n    try {\n      Class<? extends Channel> channelType = Class\n          .forName(\"io.netty.channel.epoll.EpollSocketChannel\").asSubclass(Channel.class);\n      return channelType;\n    } catch (ClassNotFoundException e) {\n      throw new RuntimeException(\"Cannot load EpollSocketChannel\", e);\n    }\n  }\n\n  // 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","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/netty/src/main/java/io/grpc/netty/Utils.java#L382-L418","documentation":"gRPC-netty tries to load io.netty.channel.epoll.EpollSocketChannel via reflection to support epoll transport on Linux. This RuntimeException wraps the ClassNotFoundException raised when the netty-transport-native-epoll artifact (or its epoll native binding) is not on the classpath. It means the code path requiring epoll was entered but the epoll classes are absent.","triggerScenarios":"Calling Utils.epollChannelType() (indirectly through Utils.DEFAULT_CHANNEL_TYPE / EpollSocketChannel type resolution) when grpc-netty selects the epoll transport — e.g. channelBuilder.channelType(Utils.epollChannelType()) or default epoll detection — while io.netty:netty-transport-native-epoll is missing from the runtime classpath.","commonSituations":"Running on Linux with an epoll transport configured but the netty-transport-native-epoll dependency excluded or not transitively pulled in; fat-jar repackaging that drops epoll natives; mismatched Netty versions where io.netty.channel.epoll classes moved; deploying to a non-Linux OS while code unconditionally requests epoll channels.","solutions":["Add the dependency io.netty:netty-transport-native-epoll with the linux-x86_64 (or relevant) classifier matching your grpc-netty version","Verify the Netty version on the classpath matches the one grpc-netty expects (mvn dependency:tree); align versions with the netty-bom","If epoll is not needed, stop requesting the epoll channel type and let gRPC use the default NIO channel (NettyChannelBuilder defaults)","Check that your build/packaging (shade plugin, container image) includes io/netty/channel/epoll/** classes and the native epoll .so library"],"exampleFix":"// before (pom.xml)\n<dependency>\n  <groupId>io.grpc</groupId>\n  <artifactId>grpc-netty</artifactId>\n</dependency>\n\n// after\n<dependency>\n  <groupId>io.grpc</groupId>\n  <artifactId>grpc-netty</artifactId>\n</dependency>\n<dependency>\n  <groupId>io.netty</groupId>\n  <artifactId>netty-transport-native-epoll</artifactId>\n  <classifier>linux-x86_64</classifier>\n</dependency>","handlingStrategy":"fallback","validationCode":"boolean epollAvailable = false;\ntry {\n  Class.forName(\"io.netty.channel.epoll.EpollSocketChannel\");\n  epollAvailable = true;\n} catch (ClassNotFoundException e) {\n  // epoll transport not on classpath\n}","typeGuard":"static boolean hasEpollTransport() {\n  try {\n    Class.forName(\"io.netty.channel.epoll.EpollSocketChannel\");\n    return true;\n  } catch (Throwable t) {\n    return false;\n  }\n}","tryCatchPattern":"try {\n  builder.channelType(io.grpc.netty.Utils.EPOLL_CHANNEL_TYPE);\n} catch (RuntimeException e) {\n  if (e.getCause() instanceof ClassNotFoundException) {\n    builder.channelType(io.netty.channel.socket.nio.NioSocketChannel.class); // fall back to NIO\n  } else {\n    throw e;\n  }\n}","preventionTips":["Always include netty-transport-native-epoll with the correct OS classifier when targeting Linux epoll","Check Utils.isEpollAvailable() (or Class.forName probe) before requesting epoll channel types","Let NettyChannelBuilder auto-detect the transport instead of hardcoding epoll","Keep Netty versions aligned with grpc-netty via netty-bom","Verify shaded/docker images retain epoll classes and native .so files"],"tags":["netty","grpc","classpath","reflection","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"}