TL;DR

1
2
3
badblocks -b 4096 -sv /dev/sdX          # read-only: touches no data
badblocks -b 4096 -nsv /dev/sdX         # non-destructive read-write (twice as slow)
badblocks -b 4096 -wsv /dev/sdX         # DESTRUCTIVE: writes patterns and wipes the whole disk

-b 4096 raises the ceiling from 4 TiB to 16 TiB. For disks over 16 TiB, -b 8192.

The error

1
badblocks: Value too large for defined data type invalid end block (7814026584): must be 32-bit value

It shows up before a single sector is read. The number is the disk’s block count at the default block size (1 KiB): 7,814,026,584 blocks is 8 TB.

Why it happens

badblocks numbers blocks with a 32-bit integer: at most 4,294,967,295. With the default 1 KiB block that is 4 TiB (about 4.4 TB as sold); any bigger disk overflows the counter. Raising the block size multiplies the ceiling:

-bCeiling
1024 (default)4 TiB
409616 TiB
819232 TiB
1638464 TiB

4096 is also the natural size: it matches the physical sector of current disks (blockdev --getpbsz /dev/sdX confirms it) and ext4’s default block, which is what matters if you are going to hand the list to e2fsck.

Which mode to use

ModeWhat it doesWhen
-sv (default)Reads the whole disk onceDisk with data; quick check
-nsvReads, writes a pattern, restores the original, block by blockDisk with data you want to test for writes. Unmounted; a power cut halfway loses the block in flight
-wsvFour write passes (0xaa, 0x55, 0xff, 0x00) with verificationNew or second-hand disk before putting data on it (burn-in)

Time: one read pass takes capacity ÷ speed (an 8 TB disk at 180 MB/s, about 13 hours); -w is eight passes (four writes and four reads), several days on big disks. Run it inside tmux or screen.

Useful options:

1
2
3
badblocks -b 4096 -c 1024 -wsv /dev/sdX          # -c: blocks per pass (more memory, somewhat faster)
badblocks -b 4096 -sv -o /root/sdX-bad.txt /dev/sdX   # -o: list of bad blocks
e2fsck -f -l /root/sdX-bad.txt /dev/sdX1              # mark them on an ext4 (same -b as the fs block)

What a modern disk does not tell badblocks

Disks remap defective sectors on their own: if badblocks finds any at all, the disk has already used up, or is using up, its spare pool. Before and after any pass, look at SMART:

1
2
3
smartctl -A /dev/sdX | grep -E 'Reallocated_Sector|Current_Pending|Offline_Uncorrectable'
smartctl -t long /dev/sdX          # long test inside the disk itself, no bus traffic
smartctl -l selftest /dev/sdX      # result once it finishes (hours)

To decide whether a second-hand disk joins the pool, smartctl -t long plus attributes 5, 197, and 198 say more than badblocks in a fraction of the time. badblocks -w still makes sense as a burn-in for a new disk, because it forces writes over the whole surface.

Traps

  • -w on the wrong device wipes the wrong disk. lsblk -o NAME,SIZE,MODEL,SERIAL before typing the command, and never on a mounted one.
  • USB-SATA bridges that reset halfway through a multi-day pass: connect the disk to SATA directly if you can. A bridge reset aborts the test and leaves no partial result.
  • mkfs.ext4 -c runs badblocks for you with the filesystem’s block size (4 KiB), so it does not overflow; but it is a mkfs, destructive by definition.
  • HPE Smart Array controllers: disks behind the controller are queried over SMART with smartctl -d cciss,N /dev/sda; badblocks sees the logical volume, not each disk.
  • On ZFS do not run badblocks on a pool member: zpool scrub does the check with real data checksums.

References: badblocks on the ArchWiki and man 8 badblocks.