SeleniumHQ/selenium · error

Failed to dlopen %s

Error message

Failed to dlopen %s

What it means

stderr diagnostic from get_xlib_handle() emitted when dlopen(library, RTLD_LAZY) returns NULL after a candidate libX11 path was successfully located by arch or env. Unlike error 501 (library not found), here the file exists and has the right ELF machine type, but the dynamic loader refused to map it. The immediately following line prints dlerror() with the precise reason. The function still returns NULL, so the focus-prevention shim is disabled exactly as in the not-found case, but the fix is different: this is a shared-library dependency or permission problem, not a missing-library problem.

Source

Thrown at cpp/linux-specific/x_ignore_nofocus.c:640

  if (suitable_xlib_index >= 0) {
    snprintf(library, MAX_LIBRARY_PATH, "%s", possible_locations[suitable_xlib_index]);
    found_library = TRUE;
  } else {
    found_library = find_xlib_by_env(library, required_lib_arch);
  }
  if (found_library == FALSE) {
    const char* desired_arch = (required_lib_arch == EM_386 ? "32-bit" : "64-bit");
    fprintf(stderr, "None of the following is a %s version of Xlib:", desired_arch);
    int i;
    for (i = 0; i < locations_len; i++) {
      fprintf(stderr, " %s\n", possible_locations[i]);
    }
    return NULL;
  }

  ret_handle = dlopen(library, RTLD_LAZY);
  if (ret_handle == NULL) {
    fprintf(stderr, "Failed to dlopen %s\n", library);
    fprintf(stderr, "dlerror says: %s\n", dlerror());
  }

  return ret_handle;
}

void print_event_to_log(Display* dpy, XEvent* ev)
{
#ifdef DEBUG_PRINTOUTS
  if ((ev->type != PropertyNotify) && (ev->type != ConfigureNotify)) {
    print_event(g_out_stream, ev, dpy);
  }
#endif
}

// This global variable is intentionally declared here - as I wish the rest
// of the functions will act on it as a parameter.
FocusKeepStatus g_focus_status;

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Read the next stderr line ('dlerror says: ...') for the exact loader error; it usually names the missing symbol or undefined library.
  2. Run `ldd <path-from-the-message>` on the dlopened libX11.so.6 and install every dependency it reports as 'not found' (commonly `apt-get install -y libxcb1 libxau6 libxdmcp6`).
  3. If on Alpine/musl, switch to a glibc-based image (or install gcompat) because the native helper is built against glibc and dlopen of a musl libX11 will fail at symbol resolution.
  4. For SELinux denials, check `ausearch -m avc -ts recent` / `dmesg | grep -i selinux` and adjust the context or set the host to permissive for diagnosis; for a corrupt .so, `apt-get install --reinstall libx11-6`.

Example fix

# before (libX11 present but dlopen fails: missing libxcb)
# stderr:
#   Failed to dlopen /usr/lib/x86_64-linux-gnu/libX11.so.6
#   dlerror says: libxcb.so.1: cannot open shared object file

# after
apt-get update && apt-get install -y libxcb1 libxau6
java -jar selenium-server.jar   # dlopen succeeds, get_xlib_handle returns non-NULL
Defensive patterns

Strategy: validation

Validate before calling

#!/usr/bin/env bash
# Validate that the located libX11 can actually be loaded before launching Selenium.
LIB="$(ldconfig -p | awk '/libX11\.so\.6$/ {print $NF; exit}')"
[ -n "$LIB" ] || { echo 'libX11.so.6 not in ldconfig cache'; exit 1; }

echo "Checking $LIB"
ldd "$LIB" | grep -i 'not found' && {
  echo 'FAIL: libX11 has unresolved dependencies; install them (libxcb1, libxau6, ...)'
  exit 1
}

# Probe an actual dlopen the way the helper will
python3 - "$LIB" <<'PY' || { echo 'FAIL: dlopen rejected libX11'; exit 1; }
import sys, ctypes
ctypes.CDLL(sys.argv[1], mode=ctypes.RTLD_LAZY)
print('OK: dlopen succeeded')
PY

Prevention

When it happens

Trigger: dlopen() fails on a found libX11.so.6 inside get_xlib_handle() — most often because a transitive dependency (libxcb.so.1, libXau.so.6, libXdmcp.so.0, libdl.so.2, or a glibc symbol version) is missing or the wrong ABI; also when SELinux/AppArmor denies the load, the .so is corrupt or truncated, or there is a glibc-vs-musl mismatch (e.g. glibc-built helper loading a musl-system libX11).

Common situations: Slimmed Alpine/musl-based images (the helper is built against glibc); containers that installed libX11 but not libxcb1/libXau6; partial apt upgrades leaving libX11 without its runtime deps; SELinux enforcing mode blocking .so load; corrupt package install; multi-arch systems pulling the wrong libxcb alongside the right libX11.

Related errors


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/33d396c8cf79070b. Report an issue: GitHub.