{"record":{"id":"218b007f7b1a00b3","repo":"grpc/grpc-java","slug":"exception-while-checking-epoll-availability","errorCode":null,"errorMessage":"Exception while checking Epoll availability","messagePattern":"Exception while checking Epoll availability","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"netty/src/main/java/io/grpc/netty/Utils.java","lineNumber":377,"sourceCode":"    if (t instanceof Http2Exception) {\n      return Status.INTERNAL.withDescription(\"http2 exception\").withCause(t);\n    }\n    return s;\n  }\n\n  @VisibleForTesting\n  static boolean isEpollAvailable() {\n    try {\n      return (boolean) (Boolean)\n          Class\n              .forName(\"io.netty.channel.epoll.Epoll\")\n              .getDeclaredMethod(\"isAvailable\")\n              .invoke(null);\n    } catch (ClassNotFoundException e) {\n      // this is normal if netty-epoll runtime dependency doesn't exist.\n      return false;\n    } catch (Exception e) {\n      throw new RuntimeException(\"Exception while checking Epoll availability\", e);\n    }\n  }\n\n  private static Throwable getEpollUnavailabilityCause() {\n    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 {","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/netty/src/main/java/io/grpc/netty/Utils.java#L359-L395","documentation":"Utils.isEpollAvailable() reflectively invokes io.netty.channel.epoll.Epoll.isAvailable(). ClassNotFoundException (epoll jar absent) is treated as \"not available\", but any other reflective failure is rethrown as an unchecked RuntimeException \"Exception while checking Epoll availability\". This indicates the epoll probe itself broke, not merely that epoll is unavailable.","triggerScenarios":"Calling isEpollAvailable() (directly or via Utils/EpollChannelOption setup on Linux) when reflective invocation of Epoll.isAvailable() throws — e.g. the native epoll library failed to load (UnsatisfiedLinkError wrapped in ExceptionInInitializerError), SecurityManager blocking reflection, or a corrupted/partial netty-transport-native-epoll installation.","commonSituations":"Deploying grpc-netty without the matching netty-transport-native-epoll classifier jar (wrong OS/arch classifier); Alpine/musl images without the glibc epoll native build; fat jars excluding native .so files; running on non-Linux with code paths that assume epoll and mishandle the exception.","solutions":["Read the cause: it reveals whether native library loading failed or reflection was blocked.","Add the correct netty-transport-native-epoll artifact for your OS/arch (or the `netty-transport-native-epoll` with linux-x86_64 classifier) matching your netty version.","Fix packaging so native .so files survive shading/fat-jar assembly, or disable epoll by using NIO (default) instead of forcing epoll.","If running on non-Linux, use the default NIO transport rather than EpollChannelType.","Call Epoll.isAvailable()/Epoll.autoDetection() semantics first and fall back to NIO when unavailable."],"exampleFix":"// before\nif (Utils.isEpollAvailable()) { ... } // throws when native lib is broken\n// after\nif (Epoll.isAvailable()) {\n  channelType = EpollDomainSocket/EpollSocketChannel; // native present\n} else {\n  channelType = NioSocketChannel; // safe fallback\n}","handlingStrategy":"fallback","validationCode":"boolean epollUsable = io.netty.channel.epoll.Epoll.isAvailable(); // no exception: returns false when jar/native missing\nClass<? extends io.netty.channel.Channel> channelType = epollUsable\n    ? io.netty.channel.epoll.EpollSocketChannel\n    : io.netty.channel.nio.NioSocketChannel;","typeGuard":"static boolean epollSafeToUse() {\n  try {\n    return Utils.isEpollAvailable();\n  } catch (RuntimeException e) {\n    return false; // treat broken epoll probe as unavailable\n  }\n}","tryCatchPattern":"try {\n  useEpoll();\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"Epoll availability\")) {\n    useNio(); // fall back to JDK NIO transport\n  }\n}","preventionTips":["Always check Epoll.isAvailable() before selecting epoll channel types","Include netty-transport-native-epoll with the right OS classifier for your platform","Verify native .so files survive shading/fat-jar packaging","Fall back to NIO on non-Linux or when natives are absent"],"tags":["grpc","java","netty","epoll","native-library","linux"],"backgroundTag":"missing-optional-dependency","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"}