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

  1. Loosen the container/sandbox seccomp profile to allow clock_gettime / clock_gettime64 (and clock_nanosleep) syscalls.
  2. Use a standard libc/runtime image that provides working clock_gettime.
  3. If the platform genuinely lacks the clocks, fall back to the NIO transport (NioEventLoopGroup) instead of kqueue.
  4. 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

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


AI-assisted analysis of netty/netty@70040aacae (2026-08-14). Data as JSON: /api/errors/c3e03130e2db6020. Report an issue: GitHub.