netty/netty · critical
FATAL: could not find a clock for clock_gettime!
Error message
FATAL: could not find a clock for clock_gettime!
What it means
Printed to stderr (not a thrown exception) during the kqueue native library's JNI_OnLoad, when netty_unix_util_initialize_wait_clock cannot obtain any usable clock via clock_gettime. That function tries CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC, CLOCK_REALTIME_COARSE, and CLOCK_REALTIME in order; if all return non-zero it gives up, prints this FATAL message, and JNI_OnLoad returns JNI_ERR — so the kqueue native transport fails to load and KQueueEventLoopGroup cannot be created.
Source
Thrown at transport-native-kqueue/src/main/c/netty_kqueue_native.c:407
if (netty_jni_util_register_natives(env, packagePrefix, NATIVE_CLASSNAME, fixed_method_table, fixed_method_table_size) != 0) {
goto error;
}
nativeRegistered = 1;
if (netty_kqueue_bsdsocket_JNI_OnLoad(env, packagePrefix) == JNI_ERR) {
goto error;
}
bsdsocketOnLoadCalled = 1;
if (netty_kqueue_eventarray_JNI_OnLoad(env, packagePrefix) == JNI_ERR) {
goto error;
}
eventarrayOnLoadCalled = 1;
// Initialize this module
if (!netty_unix_util_initialize_wait_clock(&waitClockId)) {
fprintf(stderr, "FATAL: could not find a clock for clock_gettime!\n");
fflush(stderr);
goto error;
}
staticPackagePrefix = packagePrefix;
return NETTY_JNI_UTIL_JNI_VERSION;
error:
if (staticallyRegistered == 1) {
netty_jni_util_unregister_natives(env, packagePrefix, STATICALLY_CLASSNAME);
}
if (nativeRegistered == 1) {
netty_jni_util_unregister_natives(env, packagePrefix, NATIVE_CLASSNAME);
}
if (bsdsocketOnLoadCalled == 1) {
netty_kqueue_bsdsocket_JNI_OnUnLoad(env, packagePrefix);
}
if (eventarrayOnLoadCalled == 1) {
netty_kqueue_eventarray_JNI_OnUnLoad(env, packagePrefix);View on GitHub (pinned to 70040aacae)
Solutions
- Loosen the container/sandbox seccomp profile to allow clock_gettime / clock_gettime64 (and clock_nanosleep) syscalls.
- Use a standard libc/runtime image that provides working clock_gettime.
- If the platform genuinely lacks the clocks, fall back to the NIO transport (NioEventLoopGroup) instead of kqueue.
- On macOS ensure you're on a supported release where clock_gettime is available (10.12+).
Example fix
// before - hard dependency on kqueue native transport fails to load on a restricted host
EventLoopGroup group = new KQueueEventLoopGroup();
// after - detect availability and fall back to NIO
EventLoopGroup group;
try {
group = new KQueueEventLoopGroup();
} catch (UnsatisfiedLinkError | ExceptionInInitializerError | RuntimeException e) {
group = new NioEventLoopGroup();
} Defensive patterns
Strategy: fallback
Validate before calling
// The error is a native-load failure (stderr + JNI_ERR), not a catchable decode error.
// Detect it by attempting to create the group and falling back:
EventLoopGroup group;
try {
group = new KQueueEventLoopGroup();
} catch (UnsatisfiedLinkError | ExceptionInInitializerError | RuntimeException e) {
group = new NioEventLoopGroup();
} Try / catch
try {
return new KQueueEventLoopGroup();
} catch (UnsatisfiedLinkError | ExceptionInInitializerError e) {
log.warn("kqueue native transport unavailable, falling back to NIO", e);
return new NioEventLoopGroup();
} Prevention
- Whitelist clock_gettime, clock_gettime64 and clock_nanosleep in your seccomp/container profile when using native transports.
- Test the native transport in the exact deployment image (not just dev) — sandbox policies differ.
- Always keep an NIO fallback path so a missing native transport doesn't crash the app.
- Log native-load failures loudly so a silent stderr-only message is not missed in production.
When it happens
Trigger: Loading the netty kqueue native transport on a BSD/macOS system where clock_gettime fails for every clock ID — e.g. a seccomp/container/AppArmor policy blocking clock_gettime/clock_gettime64, a stripped or broken libc, an unsupported/old kernel, or running under a sandbox that denies the time syscalls.
Common situations: Tight seccomp profiles (Docker/gVisor/sysbox) that whitelist only a few syscalls and omit the clock_gettime family; chroot/minimal images missing expected clock support; very old or non-standard BSD/macOS builds; CI sandboxes denying time syscalls.
Related errors
- readerIndex: %d, writerIndex: %d (expected: 0 <= readerIndex
- writerIndex(%d) + minWritableBytes(%d) exceeds maxCapacity(%
- length(%d) exceeds src.readableBytes(%d) where src is: %s
- length(%d) exceeds dst.writableBytes(%d) where dst is: %s
- %s: %d, length: %d (expected: range(0, %d))
AI-assisted analysis of netty/netty@70040aacae (2026-08-14).
Data as JSON: /api/errors/c3e03130e2db6020.
Report an issue: GitHub.