{"record":{"id":"e60f1f317d17f109","repo":"grpc/grpc-java","slug":"cannot-create-epoll-eventloopgroup","errorCode":null,"errorMessage":"Cannot create Epoll EventLoopGroup","messagePattern":"Cannot create Epoll EventLoopGroup","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"netty/src/main/java/io/grpc/netty/Utils.java","lineNumber":450,"sourceCode":"          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>() {\n      @Override\n      public ServerChannel newChannel() {\n        return new NioServerSocketChannel();\n      }\n    };\n  }\n\n  /**\n   * Returns TCP_USER_TIMEOUT channel option for Epoll channel if Epoll is available, otherwise\n   * null.\n   */\n  @Nullable\n  static ChannelOption<Integer> maybeGetTcpUserTimeoutOption() {","sourceCodeStart":432,"sourceCodeEnd":468,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/netty/src/main/java/io/grpc/netty/Utils.java#L432-L468","documentation":"gRPC's Netty transport tries to instantiate Netty's epoll EventLoopGroup reflectively when epoll is detected as available. If the reflective construction (EpollEventLoopGroup(parallelism, threadFactory)) throws any exception, it is wrapped in this RuntimeException. It means epoll support was present on the classpath but the actual group creation failed at runtime.","triggerScenarios":"Calling ManagedChannelBuilder/ServerBuilder forNetty with channelType/DefaultEventLoopGroup creation on Linux when netty-transport-native-epoll's native library fails to load or the constructor rejects the arguments (e.g. invalid parallelism, missing native lib for the current arch like osx-aarch_64 or musl/alpine).","commonSituations":"Running in a container or Alpine/musl image whose libc doesn't match the bundled epoll native artifact; netty-transport-native-epoll classifier mismatch with the OS/arch; EPOLL_EVENT_LOOP_GROUP_CONSTRUCTOR was non-null (class found) but native libs are absent, so Epoll.isAvailable() checks passed inconsistently or constructor fails on first use.","solutions":["Add the matching netty-transport-native-epoll classifier for your platform (e.g. linux-x86_64) so native libs are on the classpath","Verify Epoll.isAvailable() (log Epoll.unavailabilityCause()) before relying on epoll, and fall back to NIO when unavailable","Force NIO by using NettyChannelBuilder.channelType(NioSocketChannel.class)/nioServerChannelType or running on non-Linux where NIO is default","If on Alpine/musl, include the 'musl' classified native artifact or use a glibc-based image","Check that parallelism passed to the EventLoopGroup is a sane positive integer"],"exampleFix":"// before\nManagedChannel channel = NettyChannelBuilder.forAddress(host, port).build(); // picks epoll, throws\n// after\nNettyChannelBuilder builder = NettyChannelBuilder.forAddress(host, port);\nif (Epoll.isAvailable()) {\n  builder.channelType(EpollSocketChannel.class).eventLoopGroup(new EpollEventLoopGroup());\n} else {\n  builder.channelType(NioSocketChannel.class); // fallback\n}\nManagedChannel channel = builder.build();","handlingStrategy":"fallback","validationCode":"if (!Epoll.isAvailable()) {\n  throw new IllegalStateException(\"epoll unavailable: \" + Epoll.unavailabilityCause());\n}","typeGuard":"boolean epollUsable() { try { Class.forName(\"io.netty.channel.epoll.EpollEventLoopGroup\"); return Epoll.isAvailable(); } catch (ClassNotFoundException e) { return false; } }","tryCatchPattern":"try {\n  channel = NettyChannelBuilder.forAddress(host, port).build();\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Cannot create Epoll EventLoopGroup\")) {\n    channel = NettyChannelBuilder.forAddress(host, port).channelType(NioSocketChannel.class).build();\n  } else { throw e; }\n}","preventionTips":["Check Epoll.isAvailable() and log Epoll.unavailabilityCause() at startup","Add the platform-specific netty-transport-native-epoll classifier matching your runtime OS/arch","Test your image (especially Alpine/musl) for native epoll loading in CI","Prefer explicit NIO channel types when epoll is not required"],"tags":["netty","epoll","native-library","grpc","reflection"],"backgroundTag":"missing-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"}