fsck

Check a filesystem, and repair it when it needs it

Updated 2026-09-11

fsck checks a filesystem's structure and offers to repair what it finds. It is a front end: the work is done by fsck.ext4, fsck.xfs or whichever checker matches the type, and most of what looks like fsck's behaviour is really e2fsck's. Running e2fsck directly does the same thing on an ext filesystem and gives clearer messages.

Never run it on a mounted filesystem. The checker reads structures the kernel is still changing, so it reports damage that is not there, and repairing on that basis causes the corruption it was called to fix. Unmount first, and where that is the root filesystem, reboot into a rescue mode. -M makes fsck skip a mounted filesystem rather than check it.

A filesystem carries a clean flag, and a check of one that is marked clean returns immediately without looking at anything. That is why a disk with a real problem can pass instantly and why -f exists: it forces the full five-pass check regardless. Give it whenever something is wrong and fsck says nothing is.

The exit status is a bitmask rather than a number, and the three values worth knowing are 0 for no errors, 1 for errors that were corrected, and 4 for errors left uncorrected. A script that treats anything non-zero as a failure will report a successful repair as one, and 4 is the value that actually needs a person.

What it repairs it does not always return. A file whose directory entry is gone is reconnected into lost+found under its inode number rather than its name, so the recovery is of the data and not of knowing what the data was. That directory is made by mkfs when the filesystem is, which is why it exists on a filesystem nothing has ever gone wrong with.

Sample files used on this page

Every example below was run against these files. Recreate them to follow along.

a filesystem to break and repair data.img holds a 32M ext4 labelled tipsdata containing notes.txt and backups/site.tar, and blank.img is 16M of zeros. The setup script rebuilds both before every example on this page, so an example can corrupt the filesystem and leave it corrupted. debugfs -w is how the damage is made: it writes a specific, named change rather than scribbling over a block with dd, so the same error comes back every run. The same pair backs mount and blkid.

total 20912
-rw-r--r-- 1 root root 16777216 Jun 15 10:00 blank.img
-rw-r--r-- 1 root root 33554432 Jun 15 10:00 data.img
23 outputs, collapsed by default

Checking without changing anything

-n answers no to every question the checker asks, so nothing is written and the report is the whole output. Run this first on anything you care about, and read what it says before letting it repair.

Check a filesystem

fsck -n /srv/images/data.img; echo "exit $?"

A banner each from fsck and from the checker it dispatched to, then one line of answer. clean means the filesystem was marked as cleanly unmounted, and the check stopped there without examining anything.

Show output
fsck from util-linux 2.41.5
e2fsck 1.47.2 (1-Jan-2025)
tipsdata: clean, 15/8192 files, 6992/32768 blocks
exit 0

Force the check the clean flag skipped

fsck -f -n /srv/images/data.img; echo "exit $?"

-f ignores the clean flag and runs all five passes. This is the command to use when something is wrong and the check above says nothing is, which is the commonest way fsck gets dismissed as useless.

Show output
fsck from util-linux 2.41.5
e2fsck 1.47.2 (1-Jan-2025)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
tipsdata: 15/8192 files (0.0% non-contiguous), 6992/32768 blocks
exit 0

Read the clean flag directly

dumpe2fs -h /srv/images/data.img 2>/dev/null | grep -E "^Filesystem state"

The flag fsck is consulting, without running a check at all. dumpe2fs -h prints the superblock's header and sends its banner to standard error, which is what the redirect is dropping.

Show output
Filesystem state:         clean

See the flag after an unclean unmount

debugfs -w -R "ssv state 0" /srv/images/data.img >/dev/null 2>&1
dumpe2fs -h /srv/images/data.img 2>/dev/null | grep -E "^Filesystem state"

ssv state 0 sets the superblock field a crash would leave behind. A filesystem in this state is checked at the next boot whether or not anything is actually wrong with it.

Show output
Filesystem state:         not clean

Watch the check happen because of that flag

debugfs -w -R "ssv state 0" /srv/images/data.img >/dev/null 2>&1
fsck -n /srv/images/data.img

No -f this time: the flag alone is enough to make the full check run, and fsck says so. This is the delay people meet after a power cut, and on a multi-terabyte filesystem it is a long one.

Show output
fsck from util-linux 2.41.5
e2fsck 1.47.2 (1-Jan-2025)
tipsdata was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
tipsdata: 15/8192 files (0.0% non-contiguous), 6992/32768 blocks

Call the checker for the type directly

e2fsck -f -n /srv/images/data.img 2>&1 | tail -2; echo "exit $?"

fsck exists to dispatch by filesystem type and to handle several devices at once; on a single ext4 there is nothing it adds beyond its own banner. The 2>&1 matters here: the banner and the passes go to standard error and the findings to standard output, so a tail on one stream alone cuts an unpredictable place.

Show output
Pass 5: Checking group summary information
tipsdata: 15/8192 files (0.0% non-contiguous), 6992/32768 blocks
exit 0

See which checker would run

fsck -N /srv/images/data.img; echo "exit $?"

-N prints the command and does not run it. Worth checking on an unfamiliar filesystem type, since a missing fsck.<type> helper is reported as though the check itself failed.

Show output
fsck from util-linux 2.41.5
[/usr/sbin/fsck.ext4 (1) -- /srv/images/data.img] fsck.ext4 /srv/images/data.img
exit 0

Insist on a filesystem type

fsck -t ext4 -f -n /srv/images/data.img 2>&1 | tail -2; echo "exit $?"

-t skips the probe. Given the wrong type the matching checker runs anyway and reports damage everywhere, which is worth knowing before typing it from memory.

Show output
Pass 5: Checking group summary information
tipsdata: 15/8192 files (0.0% non-contiguous), 6992/32768 blocks
exit 0

Damage, and what the report looks like

The examples here corrupt the filesystem first. debugfs -w -R "freei /notes.txt" marks a file's inode free while the directory entry still points at it, which is one of the states a crash during a delete leaves behind.

Find damage without repairing it

debugfs -w -R "freei /notes.txt" /srv/images/data.img >/dev/null 2>&1
fsck -f -n /srv/images/data.img; echo "exit $?"

Every finding refused because of -n, and a warning that the filesystem still has errors. Status 4 is the one to act on: it means something is wrong and nothing was done about it.

Show output
fsck from util-linux 2.41.5
e2fsck 1.47.2 (1-Jan-2025)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Inode bitmap differences:  +14
Fix? no

Free inodes count wrong for group #0 (2033, counted=2034).
Fix? no

Free inodes count wrong (8177, counted=8178).
Fix? no


tipsdata: ********** WARNING: Filesystem still has errors **********

tipsdata: 15/8192 files (0.0% non-contiguous), 6992/32768 blocks
exit 4

Repair it

debugfs -w -R "freei /notes.txt" /srv/images/data.img >/dev/null 2>&1
fsck -f -y /srv/images/data.img; echo "exit $?"

-y answers yes to everything, which is the only practical choice on a filesystem with thousands of findings. The two counts the read-only check reported are gone, because fixing the bitmap made them right.

Show output
fsck from util-linux 2.41.5
e2fsck 1.47.2 (1-Jan-2025)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Inode bitmap differences:  +14
Fix? yes


tipsdata: ***** FILE SYSTEM WAS MODIFIED *****
tipsdata: 15/8192 files (0.0% non-contiguous), 6992/32768 blocks
exit 1

Check again after repairing

debugfs -w -R "freei /notes.txt" /srv/images/data.img >/dev/null 2>&1
fsck -f -y /srv/images/data.img >/dev/null 2>&1; echo "repair exit: $?"
fsck -f -n /srv/images/data.img 2>&1 | tail -1; echo "recheck exit: $?"

Always run the check a second time. A repair can uncover damage the first pass could not see past, and a second run returning 0 is the only thing that says the filesystem is actually consistent.

Show output
repair exit: 1
tipsdata: 15/8192 files (0.0% non-contiguous), 6992/32768 blocks
recheck exit: 0

Watch the clean flag hide the damage

debugfs -w -R "freei /notes.txt" /srv/images/data.img >/dev/null 2>&1
fsck -p /srv/images/data.img; echo "exit $?"

The filesystem is damaged and fsck says it is clean, because -p trusts the flag and the flag was never cleared. This is the case -f exists for, and the reason a disk with a real fault can pass a check in under a second.

Show output
fsck from util-linux 2.41.5
tipsdata: clean, 15/8192 files, 6992/32768 blocks
exit 0

The exit status

The status is a bitmask, so the values add: 1 for errors corrected, 2 for a reboot needed, 4 for errors left uncorrected, 8 for an operational error, 16 for a usage error. A script testing for zero alone will call a successful repair a failure.

Nothing wrong

fsck -f -n /srv/images/data.img >/dev/null 2>&1; echo "exit $?"

Zero, and the only status that means the filesystem needs nothing. Everything else is worth reading rather than retrying.

Show output
exit 0

Errors found and corrected

debugfs -w -R "freei /notes.txt" /srv/images/data.img >/dev/null 2>&1
fsck -f -y /srv/images/data.img >/dev/null 2>&1; echo "exit $?"

Status 1: something was wrong and is not any more. A monitoring check that pages on non-zero pages on this, which is how a repaired filesystem gets treated as an outage.

Show output
exit 1

Errors found and left alone

debugfs -w -R "freei /notes.txt" /srv/images/data.img >/dev/null 2>&1
fsck -f -n /srv/images/data.img >/dev/null 2>&1; echo "exit $?"

Status 4, the one that needs a person. It is what -n returns on a damaged filesystem, and what an unattended boot check returns before dropping to a maintenance shell.

Show output
exit 4

The checker could not run at all

fsck -M /srv/images/data.img >/dev/null 2>&1; echo "exit $?"

Status 8, an operational error rather than a finding about the filesystem. Here the checker wanted to ask a question and had no terminal to ask it on, which is what happens to an interactive fsck inside a script.

Show output
exit 8

Not on a mounted filesystem

A checker reads structures the kernel is still writing, so on a mounted filesystem it reports damage that is not there. Repairing on that basis is how a working disk gets destroyed.

See what a check of a mounted filesystem reports

loop=$(losetup --find --show /srv/images/data.img)
mount "$loop" /mnt/data
fsck -n "$loop" 2>&1 | tail -3

A Clear? prompt on a filesystem that is perfectly sound. The kernel has state in memory that the on-disk structures do not reflect yet, so the checker is reading a half-written picture. -n is what keeps this harmless.

Show output
Clear? no

tipsdata: 15/8192 files (0.0% non-contiguous), 6992/32768 blocks

Skip it instead

loop=$(losetup --find --show /srv/images/data.img)
mount "$loop" /mnt/data
fsck -M "$loop"; echo "exit $?"

-M leaves a mounted filesystem alone and reports success, so a script can run over several devices without knowing which of them are in use.

Show output
fsck from util-linux 2.41.5
exit 0

Unmount before checking

loop=$(losetup --find --show /srv/images/data.img)
mount "$loop" /mnt/data
umount /mnt/data
fsck -f -n "$loop" 2>&1 | tail -1; echo "exit $?"

The same device, checked properly. For a root filesystem there is no equivalent: it has to be checked from a rescue image or at boot before it is mounted.

Show output
tipsdata: 15/8192 files (0.0% non-contiguous), 6992/32768 blocks
exit 0

When the check runs by itself

Debian checks filesystems at boot in the order /etc/fstab's sixth field gives, and tune2fs sets the thresholds that decide whether a check happens at all.

Set the fstab pass order

printf '/srv/images/data.img /mnt/data ext4 loop 0 2\n' >> /etc/fstab
grep data.img /etc/fstab

The sixth field: 1 for the root filesystem, 2 for everything else, 0 to never check. Filesystems with the same non-zero number are checked in parallel, so giving two on the same physical disk the same number makes both slower.

Show output
/srv/images/data.img /mnt/data ext4 loop 0 2

Check after a number of mounts

tune2fs -c 20 /srv/images/data.img >/dev/null
tune2fs -l /srv/images/data.img | grep -E "^(Mount count|Maximum mount count)"

-c forces a check every twentieth mount. Debian leaves this off by default, on the grounds that a scheduled check on a large filesystem delays a boot by more than it is worth.

Show output
Mount count:              1
Maximum mount count:      20

Check after an interval instead

tune2fs -i 30d /srv/images/data.img >/dev/null
tune2fs -l /srv/images/data.img | grep -E "^Check interval"

-i counts elapsed time rather than mounts, which suits a machine that reboots rarely. The value is stored in seconds and printed both ways.

Show output
Check interval:           2592000 (1 month)

Turn the automatic checks off

tune2fs -c 0 -i 0 /srv/images/data.img >/dev/null
tune2fs -l /srv/images/data.img | grep -E "^(Maximum mount count|Check interval)"

Neither threshold set, which is how a Debian filesystem is shipped. A check still happens after an unclean unmount, so this turns off the scheduled ones rather than checking altogether.

Show output
Maximum mount count:      -1
Check interval:           0 (<none>)