On further investigation, this appears to be a Cygwin bug that prevents the last 48 sectors of a drive from being wiped, although it's possible that this bug is entirely unrelated to the error message.
I tested by first writing a single pass of ones to the entire disk with:
badblocks -t "1" -vws /dev/sda
I verified that this was successful on the disk by running:
od /dev/sda
I then did:
dd if=/dev/zero of=/dev/sda bs=4M status=progress
...on the entire disk. This failed with the typical I/O error. Inspecting the disk using a hex editor shows that the entire drive was successfully zeroed apart from the last 48 sectors:

I worked out that 1953525168 sectors - 48 = 1953525120 sectors, and used this figure in combination with seek
to wipe the last 48 sectors of the disk:
$ dd if=/dev/zero of=/dev/sda seek=1953525120
dd: writing to '/dev/sda': Input/output error
49+0 records in
48+1 records out
4294991871 bytes (4.3 GB, 4.0 GiB) copied, 0.230269 s, 18.7 GB/s
This successfuly zeroes the disk from sector 48 all the way until the end, which I again confirmed using a hex editor and od /dev/sda
. Note the I/O error still exists when it reaches the end, indicating that the error does not necessarily indicate a bad wipe.
Finally, I booted Linux Kali from a bootable USB and wiped the entire disk with the same command:
dd if=/dev/zero of=/dev/sda bs=4M status=progress
Checking the wiped disk with a hex editor again confirms that the command wipes the entirety of the disk with no non-zero characters remaining.
In conclusion:
Running dd
on the entire disk in Cygwin prevents the last 48 sectors from being wiped
Using seek
to selectively wipe the disk wipes the full disk, but still causes the I/O error
Wiping the entire disk from a bootable Linux system wipes the whole disk without the I/O error
For confirmation of this bug, I also ran the same dd
command on the only other spare drive I have available, a 128GB SSD, and here it also wipes all but the last 48 sectors:

dd
just fill it with zeroes? Or shouldn't ddrescue at least be able to deal with it? I also tried runningddrescue --force /dev/zero /dev/sdX
but got the exact same "Input/output error". – Hashim Aziz Nov 29 '19 at 1:39dd
command does not specify a termination, e.g. acount=
parameter. The /dev/zero pseudo-device for input has infinite length. The only way for the command to terminate is when it tries to write past the end of the device. Hence the "error". Look at the statistics thatdd
reports. Is the "number of bytes copied" represent the entire HDD? – sawdust Nov 30 '19 at 3:02dd if=/dev/zero of=/dev/sda count=1
give when run withseek=1953525119
,seek=1953525120
andseek=1953525121
respectively? – Tom Yan Dec 2 '19 at 11:27