niri-wm/niri · warning · anyhow::Error
no default icon
Error message
no default icon
What it means
load_xcursor resolves a cursor name through the xcursor theme lookup (theme.load_icon(name)), which searches the configured theme and its inherited chain in ~/.icons, ~/.local/share/icons and /usr/share/icons. 'no default icon' means the lookup returned None: no cursor theme on disk provides an icon for that name. niri treats this softly: for most icons it logs 'error loading xcursor ...' and falls back to the default, and for CursorIcon::Default it falls back to a built-in cursor, so the visible symptom is a wrong/legacy pointer rather than a crash.
Source
Thrown at src/cursor.rs:164
/// Currently used cursor_image as a cursor provider.
pub fn cursor_image(&self) -> &CursorImageStatus {
&self.current_cursor
}
/// Set new cursor image provider.
pub fn set_cursor_image(&mut self, cursor: CursorImageStatus) {
self.current_cursor = cursor;
}
/// Load the cursor with the given `name` from the file system picking the closest
/// one to the given `size`.
fn load_xcursor(theme: &CursorTheme, name: &str, size: i32) -> anyhow::Result<XCursor> {
let _span = tracy_client::span!("load_xcursor");
let path = theme
.load_icon(name)
.ok_or_else(|| anyhow!("no default icon"))?;
let mut file = File::open(path).context("error opening cursor icon file")?;
let mut buf = vec![];
file.read_to_end(&mut buf)
.context("error reading cursor icon file")?;
let mut images = parse_xcursor(&buf).context("error parsing cursor icon file")?;
let (width, height) = images
.iter()
.min_by_key(|image| (size - image.size as i32).abs())
.map(|image| (image.width, image.height))
.unwrap();
images.retain(move |image| image.width == width && image.height == height);
let animation_duration = images.iter().fold(0, |acc, image| acc + image.delay);
View on GitHub (pinned to 606284464d)
Solutions
- Install a complete cursor theme: e.g. 'pacman -S bibata-cursor-theme' / 'apt install breeze-cursor-theme' / 'dnf install google-crosextra-carlito...' style package for your distro, plus adwaita-icon-theme as a fallback.
- Point niri at a theme that actually exists: check 'ls ~/.icons ~/.local/share/icons /usr/share/icons' and set the config to the exact directory name: cursor { xcursor-theme "Bibata-Modern-Classic"; xcursor-size 24 }.
- Verify the theme provides the default cursor: 'find /usr/share/icons/<theme> -name "left_ptr*" -o -name "default*"' should return files.
- Clear stale caches/paths: unset weird XCURSOR_PATH and confirm XCURSOR_THEME matches the installed theme name.
Example fix
// before: theme not installed, every lookup logs "no default icon"
cursor {
xcursor-theme "MyMissingTheme"
xcursor-size 24
}
// after: theme that exists in /usr/share/icons
cursor {
xcursor-theme "Adwaita"
xcursor-size 24
} Defensive patterns
Strategy: fallback
Validate before calling
// Rust: confirm the theme exists and exposes a default cursor before using it
let theme = CursorTheme::new(&name, &search_paths);
let ok = theme
.load_icon("left_ptr")
.or_else(|| theme.load_icon("default"))
.is_some();
anyhow::ensure!(ok, "cursor theme '{name}' provides no default cursor; is it installed?"); Try / catch
match Self::load_xcursor(&theme, icon.name(), size) {
Ok(x) => Some(Rc::new(x)),
Err(_) => {
// niri's own pattern: unknown icons degrade to the default, default falls back to built-in
warn!("error loading xcursor {}, using fallback", icon.name());
None // caller substitutes the default/built-in cursor
}
} Prevention
- Always install a known-complete base theme (adwaita-icon-theme or breeze-cursor-theme) alongside any fancy theme.
- Set xcursor-theme to the exact directory name under ~/.icons or /usr/share/icons.
- Verify with: find /usr/share/icons/<theme> -name 'left_ptr*' — it must return files.
- After switching themes, restart the app/compositor so lookups are redone against the new theme.
When it happens
Trigger: Calling Manager::load_xcursor with a theme whose directory exists but lacks the requested icon file (e.g. a theme with only a few cursors installed), or when the configured cursor theme is not installed at all and no default theme (Adwaita/default) exists on a minimal system; also when XCURSOR_PATH/XCURSOR_THEME point somewhere unusual.
Common situations: Setting cursor-theme in niri config (or XCURSOR_THEME) to a theme that is not installed or has a different name than its directory; minimal distros/containers with no cursor theme package; partial theme installs where 'default'/'left_ptr' aliases are missing; typos in the theme name.
Related errors
AI-assisted analysis of niri-wm/niri@606284464d (2026-08-16).
Data as JSON: /api/errors/28384e887de0cf32.
Report an issue: GitHub.