grpc/grpc-java · error · RuntimeException

EpollEventLoopGroup constructor not found

Error message

EpollEventLoopGroup constructor not found

What it means

gRPC-netty found the EpollEventLoopGroup class but could not locate the expected Constructor(Class/int, ThreadFactory) via getConstructor. This RuntimeException wraps NoSuchMethodException, indicating an incompatible Netty version where the epoll event loop group no longer exposes that constructor signature.

Source

Thrown at netty/src/main/java/io/grpc/netty/Utils.java:424

    try {
      Class<? extends Channel> channelType = Class
          .forName("io.netty.channel.epoll.EpollDomainSocketChannel").asSubclass(Channel.class);
      return channelType;
    } catch (ClassNotFoundException e) {
      throw new RuntimeException("Cannot load EpollDomainSocketChannel", e);
    }
  }

  // Must call when epoll is available
  private static Constructor<? extends EventLoopGroup> epollEventLoopGroupConstructor() {
    try {
      return Class
          .forName("io.netty.channel.epoll.EpollEventLoopGroup").asSubclass(EventLoopGroup.class)
          .getConstructor(Integer.TYPE, ThreadFactory.class);
    } catch (ClassNotFoundException e) {
      throw new RuntimeException("Cannot load EpollEventLoopGroup", e);
    } catch (NoSuchMethodException e) {
      throw new RuntimeException("EpollEventLoopGroup constructor not found", e);
    }
  }

  // Must call when epoll is available
  private static Class<? extends ServerChannel> epollServerChannelType() {
    try {
      Class<? extends ServerChannel> serverSocketChannel =
          Class
              .forName("io.netty.channel.epoll.EpollServerSocketChannel")
              .asSubclass(ServerChannel.class);
      return serverSocketChannel;
    } catch (ClassNotFoundException e) {
      throw new RuntimeException("Cannot load EpollServerSocketChannel", e);
    }
  }

  private static EventLoopGroup createEpollEventLoopGroup(
      int parallelism,

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Align the Netty version to one compatible with your grpc-netty release (use the netty-bom version grpc-netty declares); run dependency:tree to find conflicts and exclude stray Netty jars
  2. Check EpollEventLoopGroup's constructors in your resolved Netty jar (javap) to confirm the (int, ThreadFactory) form exists
  3. Upgrade or downgrade grpc-netty so its reflection target matches the Netty version in use
  4. If you cannot change versions, supply your own EventLoopGroup via NettyChannelBuilder/NettyServerBuilder.eventLoopGroup(...) instead of relying on epoll autodetection

Example fix

// before (pom.xml — conflicting versions)
<dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.2.0.Final</version></dependency>

// after — pin the version grpc-netty expects
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.netty</groupId>
      <artifactId>netty-bom</artifactId>
      <version>4.1.100.Final</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
Defensive patterns

Strategy: validation

Validate before calling

static boolean epollConstructorMatches() {
  try {
    Class.forName("io.netty.channel.epoll.EpollEventLoopGroup")
        .getConstructor(Integer.TYPE, ThreadFactory.class);
    return true;
  } catch (ClassNotFoundException | NoSuchMethodException e) {
    return false;
  }
}
// assert at startup: if (!epollConstructorMatches()) log.error("Netty version incompatible with grpc-netty epoll transport");

Try / catch

try {
  return io.grpc.netty.Utils.createEpollEventLoopGroup(parallelism, threadFactory);
} catch (RuntimeException e) {
  if (e.getCause() instanceof NoSuchMethodException) {
    throw new IllegalStateException(
        "Netty version on classpath lacks EpollEventLoopGroup(int, ThreadFactory); align netty-bom with grpc-netty", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling Utils.epollEventLoopGroupConstructor() (during epoll transport setup for a channel or server) against a Netty version where io.netty.channel.epoll.EpollEventLoopGroup lacks the (Integer, ThreadFactory) constructor — typically due to a Netty upgrade or mixed Netty jar versions.

Common situations: Upgrading Netty (or a framework that pulls a newer/older Netty) while grpc-netty still expects the 4.1-era constructor; multiple Netty versions on the classpath so the resolved class differs from the one grpc-netty was compiled against; shaded/relocated epoll classes.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/490dcc22718e356e. Report an issue: GitHub.