wezterm/wezterm · error
failed to create csd frame
Error message
failed to create csd frame
What it means
Every Wayland window wezterm creates instantiates a FallbackFrame (client-side decoration frame) regardless of the negotiated decoration mode; it is only hidden when server-side decorations are active. FallbackFrame::new binds subcompositor surfaces for the borders/title bar, and any failure (missing wl_subcompositor global, shm failure, surface creation error) panics here.
Source
Thrown at window/src/os/wayland/window.rs:270
window.set_app_id(class_name.to_string());
window.set_title(name.to_string());
let decor_mode = if !config.window_decorations.contains(WindowDecorations::TITLE) {
None
} else if config.window_decorations == WindowDecorations::default() {
Some(DecorationMode::Server)
} else {
Some(DecorationMode::Client)
};
window.request_decoration_mode(decor_mode);
let mut window_frame = {
let wayland_state = &conn.wayland_state.borrow();
let shm = &wayland_state.shm;
let subcompositor = wayland_state.subcompositor.clone();
FallbackFrame::new(&window, shm, subcompositor, qh.clone())
.expect("failed to create csd frame")
};
let hidden = match decor_mode {
Some(DecorationMode::Client) => false,
_ => true,
};
window_frame.set_hidden(hidden);
if !hidden {
window_frame.resize(
NonZeroU32::new(dimensions.pixel_width as u32)
.ok_or_else(|| anyhow!("dimensions {dimensions:?} are invalid"))?,
NonZeroU32::new(dimensions.pixel_height as u32)
.ok_or_else(|| anyhow!("dimensions {dimensions:?} are invalid"))?,
);
}
window.set_min_size(Some((32, 32)));
let (x, y) = window_frame.location();
let surface_width = dimensions.pixels_to_surface(dimensions.pixel_width as i32);View on GitHub (pinned to 08e5e0afc6)
Solutions
- Check that the compositor provides wl_subcompositor: `wayland-info` (weston-info) must list it alongside wl_compositor and wl_shm
- Rule out resource exhaustion: raise `ulimit -n` and confirm memory is available, since subcompositor surface/pool creation can fail like any shm allocation
- Update wezterm — FallbackFrame construction and decoration negotiation have seen multiple fixes
- As a last resort on a limited compositor, force the X11 path with WEZTERM_ENABLE_WAYLAND=0 (requires XWayland)
Example fix
# before: panic 'failed to create csd frame' on a compositor without wl_subcompositor wayland-info | grep -i subcompositor # no output = missing global WEZTERM_ENABLE_WAYLAND=0 wezterm # after: runs via XWayland
Defensive patterns
Strategy: fallback
Validate before calling
# check that the compositor provides the subcompositor global wayland-info | grep -i subcompositor
Prevention
- Prefer compositors that expose wl_subcompositor for full CSD support
- Keep WEZTERM_ENABLE_WAYLAND=0 as a documented escape hatch on limited compositors (needs XWayland)
- Validate compositor globals (wayland-info) when certifying kiosk/embedded images
When it happens
Trigger: Fires at window creation (Window::new) on Wayland. Typical causes: the compositor does not expose the wl_subcompositor global needed to place border surfaces, or the shm/subsurface pool setup fails right after — often the same resource pressure that breaks the pointer/frame pools.
Common situations: Running against minimal or embedded compositors (kiosk Wayland servers, cage, some nested compositors) that omit wl_subcompositor; fd/memory exhaustion at startup; protocol version mismatches in older wezterm builds.
Related errors
- I/O Error while redrawing the borders
- make pixmap from existing bitmap
- Couldn't clone owned fd
- Failed to create pointer
- raw_window_handle only callable on main thread
AI-assisted analysis of wezterm/wezterm@08e5e0afc6 (2026-08-20).
Data as JSON: /api/errors/cee54d20418376d4.
Report an issue: GitHub.