fsck Command in Linux: Complete Guide to File System Checking, Repair, and Parameters

fsck command in Linux and it perimeters

There’s a very specific kind of dread that comes with a boot process stopping at Give root password for maintenance because fsck found problems it couldn’t fix automatically. I’ve been on the other side of that prompt more than once, usually after a power loss on a server without a UPS. fsck is the tool that got me out of it every time, and understanding how it actually works turned that dread into a fairly mechanical troubleshooting process. Here’s everything I know about it.

What fsck Does

fsck (File System Consistency checK) inspects a filesystem’s internal metadata — superblocks, inode tables, directory structures, block allocation bitmaps — and verifies they’re internally consistent. If it finds inconsistencies (orphaned inodes, bad block pointers, directory entries pointing nowhere, incorrect free-block counts), it can repair them, either automatically or interactively.

Like mkfs, fsck is a dispatcher, not the actual checker. Running fsck /dev/sdb1 inspects the filesystem type and calls the matching filesystem-specific checker: fsck.ext4 (technically e2fsck), fsck.xfs, fsck.vfat, fsck.btrfs, and so on. Each has its own logic because each filesystem’s on-disk structure is different.

Syntax

Verified from fsck --help on util-linux 2.39.3:

Usage:
 fsck [options] -- [fs-options] [<filesystem> ...]

Check and repair a Linux filesystem.

Options:
 -A         check all filesystems
 -C [<fd>]  display progress bar; file descriptor is for GUIs
 -l         lock the device to guarantee exclusive access
 -M         do not check mounted filesystems
 -N         do not execute, just show what would be done
 -P         check filesystems in parallel, including root
 -R         skip root filesystem; useful only with '-A'
 -r [<fd>]  report statistics for each device checked
 -s         serialize the checking operations
 -T         do not show the title on startup
 -t <type>  specify filesystem types to be checked
 -V         explain what is being done
 -?, --help     display this help
     --version  display version

Key Parameters

OptionPurpose
-ACheck every filesystem listed in /etc/fstab with a non-zero fsck pass number
-a / -pAutomatically repair without prompting (used by boot scripts)
-rInteractively prompt for confirmation before each repair
-yAssume “yes” to all repair prompts — the most common flag for unattended runs
-nAssume “no” to all prompts — safe, read-only inspection mode
-fForce a check even if the filesystem appears clean (ext-family)
-CShow a progress bar
-MSkip mounted filesystems, avoiding the dangerous case of checking a live mounted fs
-t TYPERestrict checking to a specific filesystem type
-NDry run — show what would run without executing

For ext2/3/4 specifically, the real work is done by e2fsck, which adds its own rich flag set, most notably -f (force check on a clean fs), -p (preen — auto-fix safe issues, abort on anything requiring a human), and -b superblock (use an alternate/backup superblock if the primary is corrupted).

Tested Example

I built a throwaway ext4 image, checked it clean, then walked through the standard verification pattern:

$ dd if=/dev/zero of=/home/claude/test.img bs=1M count=50
$ mkfs.ext4 -F /home/claude/test.img
$ losetup -fP /home/claude/test.img
$ losetup -j /home/claude/test.img
/dev/loop0: [...] (/home/claude/test.img)

$ fsck -N /dev/loop0
fsck from util-linux 2.39.3
[/usr/sbin/fsck.ext4 (1) -- /dev/loop0] fsck.ext4 /dev/loop0

-N shows exactly which checker fsck would invoke without running it — useful for confirming dispatch before committing to a real check.

$ fsck -f -y /dev/loop0
fsck from util-linux 2.39.3
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
/dev/loop0: 11/12800 files (9.1% non-contiguous), 1840/12800 blocks

That output walking through five numbered passes is the exact structure e2fsck always follows, and it’s worth understanding each one.

The Five e2fsck Passes Explained

  1. Pass 1 — Inode and block checking: scans every inode, validating block pointers, file sizes, and mode bits. Detects illegal or duplicate block claims.
  2. Pass 2 — Directory structure: verifies directory entries point to valid inodes and directory contents are well-formed.
  3. Pass 3 — Directory connectivity: confirms every directory can be reached from the root, reattaching orphaned directories into lost+found if not.
  4. Pass 4 — Reference counts: ensures each inode’s link count matches the number of directory entries actually referencing it.
  5. Pass 5 — Group summary information: recalculates free block/inode counts per block group and compares them against what the superblock and group descriptors claim, fixing mismatches.

Errors found early (Pass 1) often cascade into apparent errors in later passes, which is why a badly corrupted filesystem can report a long list of fixes in a single run — most stem from the same root cause.

Running fsck Safely

The single most important rule: never run fsck on a mounted, actively-written filesystem in repair mode. Read-write repair on a live filesystem races against the kernel’s own view of that filesystem and can cause worse corruption than what you started with. The safe patterns are:

  • Unmount first: umount /dev/sdb1 && fsck -y /dev/sdb1
  • Boot from a rescue/live image and check the target disk that isn’t mounted at all
  • For the root filesystem specifically, fsck normally can’t run against it live; this is handled either at boot before it’s mounted read-write, or by scheduling a forced check on next boot

Forcing a Filesystem Check on Next Boot

sudo touch /forcefsck

On many ext-family setups this legacy flag file, checked by the init scripts, forces a check on the next boot before the root filesystem is mounted read-write. On modern systemd systems, the equivalent is:

sudo systemctl reboot --force
# or, more directly:
fsck.mode=force fsck.repair=yes   # kernel boot parameter added via grub

I also frequently just directly schedule it via tune2fs mount-count-based checks:

sudo tune2fs -c 30 /dev/sda1     # force a check every 30 mounts
sudo tune2fs -l /dev/sda1 | grep -i "mount count"

Real-World Recovery Workflow

This is the sequence I actually follow when a server won’t boot after an unclean shutdown and drops to an emergency shell:

# 1. Identify the affected filesystem
lsblk -f

# 2. Confirm it's unmounted (rescue shells usually mount root read-only or not at all)
mount | grep sda1

# 3. If mounted read-write, remount read-only or unmount
mount -o remount,ro /dev/sda1

# 4. Run a forced, interactive check first to see the scope of damage
fsck -f -n /dev/sda1

# 5. If the issues look like standard, safe-to-fix inconsistencies, rerun with auto-repair
fsck -f -y /dev/sda1

# 6. Reboot and confirm system comes up clean
reboot

Running the -n (no-repair) pass first is a habit I picked up after fixing something the “wrong” way early in my career — a dry look at what’s wrong lets you judge whether this is routine post-crash cleanup or something more serious (failing disk, mismatched superblock) that deserves a backup pass before you let fsck start moving things into lost+found.

Automation Example: Scheduled Health Check Across All Mounts

#!/bin/bash
set -euo pipefail
LOGFILE="/var/log/fsck-report-$(date +%F).log"

echo "Starting non-destructive filesystem check: $(date)" | tee -a "$LOGFILE"

for fs in $(lsblk -rno NAME,MOUNTPOINT | awk '$2!="" {print "/dev/"$1}'); do
  if mount | grep -q "^$fs "; then
    echo "Skipping $fs (currently mounted, live check unsafe)" | tee -a "$LOGFILE"
    continue
  fi
  echo "Checking $fs ..." | tee -a "$LOGFILE"
  fsck -n "$fs" >> "$LOGFILE" 2>&1 || echo "Issues found on $fs" | tee -a "$LOGFILE"
done

echo "Completed: $(date)" | tee -a "$LOGFILE"

This intentionally only runs -n (dry, no-repair) checks on unmounted devices, generating a report I can review before ever authorizing a repair pass — that separation between “detect” and “fix” is deliberate for anything touching production data.

Troubleshooting

“UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY” — the automatic boot-time check found something it won’t fix without confirmation; boot into single-user/rescue mode and run fsck by hand with -y.

Bad superblock / “fsck.ext4: Superblock invalid” — the primary superblock is corrupted. ext4 keeps backups; find one with mke2fs -n /dev/sdX (dry run shows expected backup superblock locations) and repair with fsck -b 32768 /dev/sdX (or whichever offset applies).

fsck loops, reporting the same errors every run — usually indicates underlying hardware failure (bad sectors) rather than a simple metadata inconsistency; check smartctl -a /dev/sdX and dmesg for I/O errors before trusting further repairs.

System stuck at boot on fsck for a very large filesystem — this is expected for multi-terabyte volumes with heavy fragmentation; consider -C for progress visibility, and long-term, disable forced periodic checks on large data volumes (tune2fs -c 0 -i 0) if you rely on other integrity mechanisms (RAID scrubbing, backups) instead.

Performance Optimization

  • Skip full inode scans when unnecessary — a normal fsck run on a cleanly unmounted ext4 filesystem exits almost instantly because the superblock’s “clean” flag is set; only pass -f when you specifically need to force a full pass.
  • Use -P for parallel checks across multiple independent devices during boot or maintenance windows, cutting wall-clock time significantly on multi-disk servers.
  • Disable periodic forced checks on large SSD-backed volumes with tune2fs -c 0 -i 0, since the checks were originally designed around spinning-disk failure patterns and now mostly just add downtime for volumes protected by RAID/redundant storage or frequent backups.
  • XFS note: xfs_repair (fsck.xfs’s actual worker) does not run online consistency checks the way e2fsck does; XFS relies more heavily on its journal for crash recovery, and full xfs_repair runs are comparatively rare and reserved for real corruption, not routine boot checks.

fsck vs Related Commands

CommandPurpose
fsck / fsck.*Checks and repairs an existing filesystem’s metadata consistency
e2fsckThe actual ext2/3/4 checker invoked by fsck.ext4
xfs_repairXFS’s equivalent checker/repair tool, invoked via fsck.xfs (which mostly just defers)
badblocksScans for physical bad sectors, a lower layer than filesystem metadata
smartctlReads drive health/SMART data, useful to rule out hardware failure before blaming the filesystem
mkfsCreates a fresh filesystem; the opposite operation of repairing an existing one

Security Implications

Automatic, unattended -y repairs are convenient but not risk-free: badly timed automatic repairs on a filesystem with real corruption can silently relocate or delete data into lost+found without a human reviewing what was lost. On systems holding data you can’t afford to lose, I always keep verified backups current enough that an aggressive fsck -y run is never itself the single point of failure. Also worth noting: fsck typically requires root, since arbitrary read/write access to raw block devices is inherently privileged — treat any account with permission to run it against production disks as having effectively full data access.

Distribution Compatibility

fsck and its ext-family backend e2fsck (from e2fsprogs) ship on every major distribution by default, since virtually every distro needs to check its own root filesystem at boot. XFS tooling (xfsprogs) and Btrfs tooling (btrfs-progs) may need explicit installation on minimal images. Boot-time integration differs slightly: systemd-based distros (Ubuntu, Fedora, Debian, Arch, RHEL 8+) use systemd-fsck units gating mount ordering, while older SysV-init systems used /etc/init.d scripts calling fsck -A directly — functionally similar outcomes, different orchestration.

fsck and Journaling: Why Modern Filesystems Need It Less Often

A question I get asked often: if ext4, XFS, and Btrfs all maintain a metadata journal specifically to survive unclean shutdowns, why does fsck still exist and matter? The journal handles the common case — replaying incomplete transactions after a crash so metadata returns to a consistent state, which happens automatically at mount time without any explicit fsck invocation needed. What the journal does not protect against is corruption from causes outside its scope entirely: failing storage hardware silently returning bad data, bugs in the filesystem driver itself, bit flips from unreliable RAM (which is exactly why ECC memory matters more on storage servers than people often assume), or manual/administrative mistakes like a botched dd or partition table edit. fsck‘s full structural walk exists precisely to catch that broader class of problem that journal replay was never designed to address, which is why periodic full checks still have value even on modern, robustly-journaled filesystems, particularly on hardware you have reason to distrust.

Checking Filesystem Status Without a Full Scan

Before committing to a potentially long fsck -f run on a large volume, dumpe2fs gives a fast, read-only look at an ext4 filesystem’s recorded state, including whether it was cleanly unmounted:

dumpe2fs -h /dev/sda1 | grep -i state
Filesystem state:        clean

If this reports clean, a routine fsck without -f will exit almost instantly, since the filesystem itself is asserting no repair is needed — useful context before scheduling a maintenance window around what you assume will be a lengthy check.

fsck Exit Codes for Scripting

fsck‘s exit code is a bitmask, not a simple success/failure boolean, and any automation branching on its result needs to account for this:

Bit valueMeaning
0No errors
1Filesystem errors corrected
2System should be rebooted
4Filesystem errors left uncorrected
8Operational error
16Usage or syntax error
32Fsck canceled by user request
128Shared library error

A script checking $? -eq 0 alone will miss the meaningfully different case of “errors were corrected but a reboot is now required” (exit code 2) — worth handling explicitly in any automated boot-time or maintenance-window fsck orchestration rather than treating every non-zero result identically.

Summary

fsck is the safety net underneath every Linux filesystem, and understanding its five-pass model, the difference between dry-run inspection and destructive repair, and the hard rule against checking mounted filesystems turns what feels like an emergency into a routine, predictable procedure. I treat a clean fsck -n pass as a diagnostic first step, and only escalate to -y once I understand what’s actually wrong.

References

  • util-linux — fsck(8): https://man7.org/linux/man-pages/man8/fsck.8.html
  • e2fsprogs — e2fsck(8): https://man7.org/linux/man-pages/man8/e2fsck.8.html
  • XFS Documentation — xfs_repair(8): https://man7.org/linux/man-pages/man8/xfs_repair.8.html
  • Red Hat Documentation — Filesystem Recovery: https://access.redhat.com/documentation/
  • Ubuntu Server Guide — Storage Administration: https://ubuntu.com/server/docs
Total
0
Shares

Leave a Reply

Previous Post
fdisk command in Linux and it perimeters

fdisk Command in Linux: Complete Guide to Disk Partitioning and Parameters

Next Post
mkfs command in Linux and it perimeters

mkfs Command in Linux: Complete Guide to Building File Systems and Parameters

Related Posts