wezterm/wezterm · error · anyhow::Error

failed to query locale

Error message

failed to query locale

What it means

query_lc_ctype calls libc setlocale(LC_CTYPE, NULL) to query the current LC_CTYPE setting, which returns a pointer to the locale string. A NULL return means the C library could not report a locale at all — typically because the process never had a valid LC_CTYPE (someone called setlocale with an unavailable name earlier) or the environment names a locale that isn't generated on the system. wezterm uses the result to feed locale-aware text handling on X11.

Source

Thrown at window/src/os/x11/keyboard.rs:825

        ensure!(
            !new_keymap.get_raw_ptr().is_null(),
            "problem with new keymap"
        );

        let new_state = xkb::x11::state_new_from_device(&new_keymap, connection, self.device_id);
        ensure!(!new_state.get_raw_ptr().is_null(), "problem with new state");
        let phys_code_map = build_physkeycode_map(&new_keymap);

        self.state.replace(new_state);
        self.keymap.replace(new_keymap);
        self.phys_code_map.replace(phys_code_map);
        Ok(())
    }
}

fn query_lc_ctype() -> anyhow::Result<&'static OsStr> {
    let ptr = unsafe { libc::setlocale(libc::LC_CTYPE, std::ptr::null()) };
    ensure!(!ptr.is_null(), "failed to query locale");
    let cstr = unsafe { CStr::from_ptr(ptr) };
    Ok(OsStr::from_bytes(cstr.to_bytes()))
}

fn build_physkeycode_map(keymap: &xkb::Keymap) -> HashMap<xkb::Keycode, PhysKeyCode> {
    let mut map = HashMap::new();

    // See <https://abaines.me.uk/updates/linux-x11-keys> for info on
    // these names and how they relate to the ANSI standard US keyboard
    // See also </usr/share/X11/xkb/keycodes/evdev> on a Linux system
    // to examine the mapping. FreeBSD and other unixes will use a different
    // set of keycode values.
    // We're using the symbolic names here to look up the keycodes that
    // correspond to the various key locations.
    for (name, phys) in &[
        ("ESC", PhysKeyCode::Escape),
        ("FK01", PhysKeyCode::F1),
        ("FK02", PhysKeyCode::F2),

View on GitHub (pinned to 3ff7522b96)

Solutions

  1. Set a safe locale explicitly before launching: `LC_ALL=C.UTF-8 wezterm` (C.UTF-8 needs no generated data on glibc)
  2. Generate the requested locale on the host: Debian/Ubuntu — edit /etc/locale.gen, run locale-gen; Arch — locale-gen after /etc/locale.conf; Alpine — apk add musl-locales or use C.UTF-8
  3. For SSH breakage, either install the client's locale on the server or configure sshd with AcceptEnv restricted / SendEnv disabled so bad LANG is not forwarded
  4. Verify with `locale` — every printed variable should name a locale listed by `locale -a`

Example fix

# before: locale not generated, setlocale query fails
$ LANG=en_US.UTF-8 wezterm

# after: use the always-available C.UTF-8
$ LC_ALL=C.UTF-8 wezterm
Defensive patterns

Strategy: validation

Validate before calling

// ensure a usable locale before starting X11-dependent code
let name = std::env::var("LC_ALL")
    .or_else(|_| std::env::var("LC_CTYPE"))
    .or_else(|_| std::env::var("LANG"))
    .unwrap_or_else(|_| "C.UTF-8".into());
if !name.ends_with("UTF-8") && name != "C" {
    std::env::set_var("LC_CTYPE", "C.UTF-8");
}

Try / catch

let lc_ctype = query_lc_ctype().unwrap_or_else(|err| {
    log::warn!("locale query failed ({err:#}); defaulting to C.UTF-8");
    OsStr::from_bytes(b"C.UTF-8")
});

Prevention

When it happens

Trigger: LANG/LC_ALL/LC_CTYPE set to a locale that is not generated (e.g. 'en_US.UTF-8' on a minimal image where locales were never produced), leaving the C runtime with no usable LC_CTYPE; setlocale called earlier with an invalid name; chroot/sandbox without /usr/lib/locale data.

Common situations: Minimal Docker/Alpine images without locale-gen; SSH sessions forwarding LANG from a client whose locale the server lacks; Nix/Flatpak sandboxes with empty /usr/lib/locale; systems where only 'C' locale exists but env demands UTF-8.

Related errors


AI-assisted analysis of wezterm/wezterm@3ff7522b96 (2026-08-20). Data as JSON: /api/errors/ffa939911833c64b. Report an issue: GitHub.