{"record":{"id":"6cd883cfe3496400","repo":"kovidgoyal/kitty","slug":"failed-to-allocate-space-for-new-disk-cache-file-d","errorCode":null,"errorMessage":"Failed to allocate space for new disk cache file during defrag","messagePattern":"Failed to allocate space for new disk cache file during defrag","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kitty/disk-cache.c","lineNumber":246,"sourceCode":"    defrag_entries = calloc(num_entries, sizeof(DefragEntry));\n    if (!defrag_entries) goto cleanup;\n    size_t total_data_size = 0, num_entries_to_defrag = 0;\n    cache_map_for_loop(i) {\n        CacheValue *s = i.data->val;\n        if (s->pos_in_cache_file > -1 && s->data_sz) {\n            total_data_size += s->data_sz;\n            DefragEntry *e = defrag_entries + num_entries_to_defrag++;\n            e->old_offset = s->pos_in_cache_file;\n            e->data_sz = s->data_sz;\n            e->key = keydup(i.data->key); // have to dup the key as we release the mutex and another thread might free the underlying key.\n            if (!e->key.hash_key) {\n                fprintf(stderr, \"Failed to allocate space for keydup in defrag\\n\");\n                goto cleanup;\n            }\n        }\n    }\n    if (ftruncate(new_cache_file, total_data_size) != 0) {\n        perror(\"Failed to allocate space for new disk cache file during defrag\");\n        goto cleanup;\n    }\n    lseek(new_cache_file, 0, SEEK_SET);\n\n    mutex(unlock);\n    lock_released = true;\n\n    off_t current_pos = 0;\n    for (size_t i = 0; i < num_entries_to_defrag; i++) {\n        DefragEntry *e = defrag_entries + i;\n        if (!copy_between_files(self->cache_file_fd, new_cache_file, e->old_offset, e->data_sz, &fcb)) {\n            perror(\"Failed to copy data to new disk cache file during defrag\");\n            goto cleanup;\n        }\n        e->new_offset = current_pos;\n        current_pos += e->data_sz;\n    }\n    ok = true;","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/disk-cache.c#L228-L264","documentation":"During disk-cache defrag, ftruncate() on the newly opened cache file failed, so kitty could not pre-allocate space for the compacted entries. Almost always ENOSPC — the filesystem holding the cache cannot fit total_data_size bytes. Defrag aborts cleanly; data remains in the old file.","triggerScenarios":"defrag() runs (triggered from find_cache_entry_to_write once fragmentation thresholds are met) and the sum of live entry sizes exceeds free space on the cache filesystem, or the fs doesn't support ftruncate (some FUSE/network mounts return EPERM/EINVAL).","commonSituations":"Large scrollback caches on a small tmpfs; cache dir on a full home partition; cache on a network filesystem (NFS) with locking/truncate quirks.","solutions":["Free space on the filesystem containing the cache dir or move XDG_CACHE_HOME to a larger volume.","Clear the old cache: quit kitty and delete the kitty disk-cache directory.","Reduce scrollback size in kitty.conf to shrink total_data_size.","Avoid putting the cache on FUSE/NFS mounts; keep it on a local fs."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"df -h \"${XDG_CACHE_HOME:-$HOME/.cache}\"  # confirm free bytes > expected scrollback cache size","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Trim scrollback_pager_history / scrollback limits on small disks.","Clear stale cache after crashes."],"tags":["disk-cache","ftruncate","enospc","kitty"],"backgroundTag":"disk-space-exhausted","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}