kovidgoyal/kitty · warning
Failed to open second file for defrag of disk cache
Error message
Failed to open second file for defrag of disk cache
What it means
While defragmenting the scrollback disk cache, kitty failed to open a second cache file in the cache directory. open_cache_file returned -1, so the defrag pass aborts (defrag is best-effort: entries stay in the fragmented file until the next attempt). Typical causes are ENOSPC (no inodes/space), EMFILE (fd limit), or permission problems on the cache dir.
Source
Thrown at kitty/disk-cache.c:225
vt_cleanup(&holes->end_pos_map);
holes->largest_hole_size = 0;
}
static void
defrag(DiskCache *self) {
int new_cache_file = -1;
RAII_ALLOC(DefragEntry, defrag_entries, NULL);
RAII_FreeFastFileCopyBuffer(fcb);
bool lock_released = false, ok = false;
off_t size_on_disk = self->end_of_data_offset;
if (size_on_disk <= 0) goto cleanup;
size_t num_entries = vt_size(&self->map);
if (!num_entries) goto cleanup;
bool opened_securely;
new_cache_file = open_cache_file(self->cache_dir, &opened_securely);
if (new_cache_file < 0) {
perror("Failed to open second file for defrag of disk cache");
goto cleanup;
}
defrag_entries = calloc(num_entries, sizeof(DefragEntry));
if (!defrag_entries) goto cleanup;
size_t total_data_size = 0, num_entries_to_defrag = 0;
cache_map_for_loop(i) {
CacheValue *s = i.data->val;
if (s->pos_in_cache_file > -1 && s->data_sz) {
total_data_size += s->data_sz;
DefragEntry *e = defrag_entries + num_entries_to_defrag++;
e->old_offset = s->pos_in_cache_file;
e->data_sz = s->data_sz;
e->key = keydup(i.data->key); // have to dup the key as we release the mutex and another thread might free the underlying key.
if (!e->key.hash_key) {
fprintf(stderr, "Failed to allocate space for keydup in defrag\n");
goto cleanup;
}
}View on GitHub (pinned to 6d5d0c4406)
Solutions
- Free space / raise inode availability on the filesystem holding kitty's cache dir (usually $XDG_CACHE_HOME/kitty).
- Check `ulimit -n` and raise it if the process is near its fd limit.
- Verify permissions on the cache directory and delete stale files in it (they are safe to remove when kitty is closed).
- If on a constrained system, disable or reduce the disk cache via kitty.conf scrollback settings (e.g. smaller scrollback_pager_history).
Defensive patterns
Strategy: validation
Validate before calling
df -h "${XDG_CACHE_HOME:-$HOME/.cache}" && df -i "${XDG_CACHE_HOME:-$HOME/.cache}" # ensure free space+inodes before heavy scrollback sessions Prevention
- Keep free space on the cache filesystem.
- Periodically clear kitty's cache dir while kitty is closed.
- Don't put XDG_CACHE_HOME on read-only or FUSE mounts.
When it happens
Trigger: Calling anything that triggers find_cache_entry_to_write (large scrollback being written to the disk cache) after the cache dir is full, read-only, has a stale lock, or the process hit its open-file limit while opening the new cache file for defrag.
Common situations: Tiny TMPFS /tmp or full XDG_CACHE_HOME when scrollback_font_size / heavy scrollback fills the disk; home directory mounted read-only (sandbox/flatpak); ulimit -n too low with many kittens.
Related errors
- Failed to allocate space for new disk cache file during defr
- Failed to copy data to new disk cache file during defrag
- Failed to write to disk-cache file
- Failed to seek in disk cache file
- This must be run as kitten ask
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/6cab132f5990801f.
Report an issue: GitHub.