SeleniumHQ/selenium · warning
None of the following is a %s version of Xlib:
Error message
None of the following is a %s version of Xlib:
What it means
This is a stderr diagnostic, not a raised exception, emitted by get_xlib_handle() in Selenium's Linux native helper x_ignore_nofocus.so. After scanning the five hardcoded libX11.so.6 candidate paths and the LD_LIBRARY_PATH-derived paths (find_xlib_by_env) and ELF-checking each against the required machine type (EM_386 for 32-bit, EM_X86_64 for 64-bit, chosen via is_32bit_system()/is_emulated_32bit()), none matched. The function prints this line, then lists each candidate, then returns NULL, which disables the focus-stealing-prevention shim and degrades native-event focus handling. It is the root-cause line; the per-path ' %s\n' lines that follow are its continuation.
Source
Thrown at cpp/linux-specific/x_ignore_nofocus.c:630
int locations_len = sizeof(possible_locations) / sizeof(char*);
uint16_t required_lib_arch;
if (is_32bit_system() || is_emulated_32bit()) {
required_lib_arch = EM_386;
} else {
required_lib_arch = EM_X86_64;
}
int suitable_xlib_index = find_xlib_by_arch(possible_locations, locations_len, required_lib_arch);
int found_library = FALSE;
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)
{View on GitHub (pinned to aa36b38e69)
Solutions
- Install the architecture-matching libX11: on Debian/Ubuntu 64-bit run `apt-get install -y libx11-6`; for 32-bit on a 64-bit host add `:i386` (`dpkg --add-architecture i386 && apt-get install -y libx11-6:i386`).
- If libX11 is installed in a non-scanned path, export `LD_LIBRARY_PATH` pointing at the directory containing the correct-arch libX11.so.6 before launching the JVM/browser, so find_xlib_by_env succeeds.
- Align architectures: run a 64-bit browser with a 64-bit JVM (and libX11), or a 32-bit browser with 32-bit libX11; mixing is the most common trigger.
- Verify with `file $(ldconfig -p | grep libX11.so.6 | awk '{print $NF}' | head -1)` that the ELF machine type matches the required arch; if not, install the matching package.
Example fix
# before (64-bit JVM, container with only 32-bit libX11) java -jar selenium-server.jar # get_xlib_handle prints 'None of the following is a 64-bit version of Xlib:' # after apt-get update && apt-get install -y libx11-6 java -jar selenium-server.jar # find_xlib_by_arch matches /usr/lib/x86_64-linux-gnu/libX11.so.6
Defensive patterns
Strategy: validation
Validate before calling
#!/usr/bin/env bash
# Run before launching the JVM/Selenium Server on Linux.
REQUIRED_ARCH="64-bit" # set to 32-bit for a 32-bit browser/JVM
candidates=(
/usr/lib/libX11.so.6
/usr/lib/x86_64-linux-gnu/libX11.so.6
/usr/lib/i386-linux-gnu/libX11.so.6
/usr/lib64/libX11.so.6
/usr/lib32/libX11.so.6
)
match=0
for lib in "${candidates[@]}"; do
[ -f "$lib" ] || continue
arch=$(file -L "$lib" | grep -o 'ELF 32-bit\|ELF 64-bit')
if [ "${arch#ELF }" = "$REQUIRED_ARCH" ]; then
echo "OK: $lib ($arch)"; match=1; break
fi
echo "SKIP: $lib ($arch)"
done
if [ "$match" -eq 0 ] && [ -n "$LD_LIBRARY_PATH" ]; then
for d in "${LD_LIBRARY_PATH//:/ }"; do
lib="$d/libX11.so.6"; [ -f "$lib" ] || continue
arch=$(file -L "$lib" | grep -o 'ELF 32-bit\|ELF 64-bit')
[ "${arch#ELF }" = "$REQUIRED_ARCH" ] && { echo "OK(env): $lib"; match=1; break; }
done
fi
[ "$match" -eq 1 ] || { echo "FAIL: no $REQUIRED_ARCH libX11 found"; exit 1; } Prevention
- Bake `apt-get install -y libx11-6` (and :i386 for 32-bit browsers) into your Dockerfile so the arch match is guaranteed at build time.
- Keep JVM, browser, and libX11 on the same architecture; do not run a 32-bit browser on a 64-bit JVM without multilib packages.
- If libX11 lives outside the five scanned paths, set LD_LIBRARY_PATH in the same script that launches the JVM.
- Add the validation script above as a CI preflight gate so arch-mismatch failures surface before the Selenium suite runs.
When it happens
Trigger: get_xlib_handle() runs at JVM/native-helper load time on Linux: required_lib_arch resolves to EM_X86_64 (or EM_386) and find_xlib_by_arch returns -1 for every entry in possible_locations, AND find_xlib_by_env also returns FALSE (no usable LD_LIBRARY_PATH entry of the right arch). Concretely: 64-bit JVM/browser on a host whose libX11.so.6 is only the 32-bit Debian/Ubuntu variant, or vice-versa, or a host where none of the five paths exist at all.
Common situations: Minimal Docker/headless containers that omit libX11 or ship only one architecture; mixed 32/64-bit setups running a 32-bit browser on a 64-bit host without the i386 multilib packages; custom distros whose libX11 lives outside the five scanned locations and LD_LIBRARY_PATH is unset; systems where libX11 was removed during image slimming.
Related errors
- %s
- Failed to dlopen %s
- Unable to obtain browser driver. For more informatio
- Unable to obtain Selenium Manager at ${filePath}
- Error executing command for ${smBinary} with ${args}: ${erro
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/a1013cd64f990c60.
Report an issue: GitHub.