Troubleshooting
Scope: the ways a disk-usage answer can look wrong, each as symptom → cause → fix. Nearly all of them resolve into the three questions this guide has asked throughout: which size is this, what was excluded, and how old is the scan?
The rows add up to more than the total
Symptom: a directory's entries sum — by your arithmetic — to more than its row claims.
Cause: hard links, chapter 3. Every
name displays at full size; the total
counts the shared data once. In the lab's
holiday/: rows 3.0 + 3.0 + 2.0 MiB,
total 5.0 MiB, and both are right.
Fix: none needed. Look for H flags,
and check a suspect file's Links tab
(i, then 2).
ncdu and du (or the file manager) disagree
Symptom: same tree, different totals, sometimes wildly.
Cause: usually the two rulers — one side showing apparent size, the other disk usage. The lab's footer pair (68.9 MiB vs 168.8 MiB) is ncdu disagreeing with itself by 100 MiB of sparse file. Other mixes: one tool crossed filesystems the other skipped, one run excluded what the other counted, one of them is an old scan (next entry).
Fix: align the options before
comparing the answers — same tree, -x
both or neither, apparent both or
neither (chapter 3's reconciliation
table). If they still differ, one is a
photograph of an earlier disk.
The numbers don't move while the disk does
Symptom: you delete or download gigabytes in another window; ncdu's totals sit still.
Cause: the browser shows the scan, not the disk. Nothing refreshes on its own.
Fix: r rescans the directory you
are standing in (chapter 2's verified
before/after). For a from-scratch truth,
quit and rescan.
I deleted it and the disk is still full
The classic, in both its forms.
Form one: the name went, the data stayed — hard links (chapter 5). You deleted one name of several. The space returns when the last name goes.
Form two: the file is gone and still holding its blocks — a program has the deleted file open. The name is removed; the inode lives until the last open handle closes. Verified on the bench: a 20 MiB file, opened by a Python process and unlinked —
$ ls opentest/ ; du -B1 opentest
0 opentest ← name gone, du sees nothing
$ ls -l /proc/<pid>/fd/
… 3 -> /home/.../opentest/held.bin (deleted)
fstat: size 20971520, blocks 40960 ← still allocated
Fix: find the holder and let it let
go — restart the service, or check
lsof +L1, which lists exactly these
files ("deleted, link count 0"). Logs
held by a daemon that never reopens them
are the everyday case: the daemon keeps
writing to a file with no name while the
disk stays full and every scan looks
innocent. This is also why a full disk
can stay full after a correct cleanup:
you freed names, not blocks.
And check the obvious: you may have
cleaned a different filesystem from the
full one. df names the full mount;
ncdu's -x (chapter 4) keeps a scan
inside it. On ext filesystems there is
one further suspect — a percentage
(5% by default) is reserved for root, so
a disk can report full to everyone else
with space still visible to root's tools.
Stated from filesystem documentation, not
measured on the lab.
A total is too small, and there's a !
Symptom: a directory shows ! and
0.0 B, or the whole tree's total is
suspiciously light.
Cause: the scan could not read it — permissions. The specimen from the build (scanned as an unprivileged user): a locked directory holding 200,000 bytes appears as
100.0 KiB [##############] /open
! 0.0 B [ ] /locked
and the export records it plainly —
{"name":"locked","asize":60,
"read_error":true} — while the scan
exits successfully and every other number
looks normal. The totals exclude what
could not be read, and only the flag says
so.
Fix: scan as a user who can read the
tree (the owner, or root), and treat any
! (or a . — a subdirectory below had
the error) as "this answer has a hole in
it." Chapter 7's blind-spot recipe greps
an export for read_error before trusting
it.
ncdu in a script or cron job does nothing
Symptom: from a script, ncdu exits at once with:
Standard input is not a TTY. Did you mean to import a file using '-f -'?
Cause: the interactive browser needs a terminal; a script hasn't got one.
Fix: script the export, not the
browser: ncdu -0 -o file dir (chapter
6). Browse the file later, interactively,
where terminals exist.
"Error: could not open …"
Two verified texts, two different diseases:
Error: could not open /does/not/exist
Error obtaining full path: No such file or directory
— the path is wrong; the fix is the path.
Error: could not open export-2.9.bin
Zero-byte found in JSON stream
— the file is fine and the reader is wrong for it: a 2.x binary or compressed export handed to 1.19 (chapter 6's matrix). Re-export as JSON, or read it with 2.x.
The borders draw as letters
Symptom: window borders appear as
lqqqk / x…x / mqqqj instead of lines.
Cause: the terminal is not in a UTF-8 mode (seen on the bench in a tmux session without a UTF-8 locale). ncdu draws with the characters the terminal offers it.
Fix: a UTF-8 locale (LANG ending in
.UTF-8) and a matching TERM. Cosmetic
only — every number was still correct.
Colours are unreadable
Symptom: the listing is coloured, and on your terminal the colours clash.
Cause: colour defaults changed over the versions (on in late 1.x, off again in recent 2.x, per the upstream notes).
Fix: --color off, or --color dark
on a dark terminal; 2.x can keep the
choice in its config file.
The scan of a huge tree is slow, or eats memory
Cause: by design, the scan lives in
memory — every entry, held for browsing.
Tens of millions of entries are tens of
millions of records, and -e adds
metadata to each.
Fix, in order: scan the subtree you
actually suspect, not /; drop -e for
the first pass; on a slow connection add
-q. For trees that outgrow RAM, 2.x's
binary export (chapter 6) is the upstream
answer — it can be browsed without being
loaded whole. Stated at documentation
level; the lab's 59 entries stress
nothing.