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
- 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
- Check EpollEventLoopGroup's constructors in your resolved Netty jar (javap) to confirm the (int, ThreadFactory) form exists
- Upgrade or downgrade grpc-netty so its reflection target matches the Netty version in use
- 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
- Import netty-bom at the exact version grpc-netty declares; never let netty-all override it
- Run dependency:tree in CI and fail on multiple Netty versions
- Check EpollEventLoopGroup constructors with javap after any Netty upgrade
- Prefer builder.eventLoopGroup(...) with a concrete group over reflective transport selection when versions drift
- Keep grpc-netty and Netty upgraded together
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
- Cannot load EpollSocketChannel
- Cannot create Epoll EventLoopGroup
- Exception while checking Epoll availability
- Cannot load EpollDomainSocketChannel
- Cannot load EpollEventLoopGroup
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/490dcc22718e356e.
Report an issue: GitHub.