Although this is not a direct answer to your question, but it may give you some insight.
First of all for some reason badblocks seem to report a bad block for "last block + 1" anyway (while for "last block + 2" or higher, it correctly return a seek error):
[tom@alarm ~]$ sudo badblocks /dev/mmcblk0 -b 512 -v 31116287 31116287
Checking blocks 31116287 to 31116287
Checking for bad blocks (read-only test): done
Pass completed, 0 bad blocks found. (0/0/0 errors)
[tom@alarm ~]$ sudo badblocks /dev/mmcblk0 -b 512 -v 31116288 31116288
Checking blocks 31116288 to 31116288
Checking for bad blocks (read-only test): 31116288
done
Pass completed, 1 bad blocks found. (1/0/0 errors)
[tom@alarm ~]$ sudo badblocks /dev/mmcblk0 -b 512 -v 31116289 31116289
Checking blocks 31116289 to 31116289
Checking for bad blocks (read-only test): badblocks: Invalid argument during seek
done
Pass completed, 0 bad blocks found. (0/0/0 errors)
[tom@alarm ~]$ sudo badblocks /dev/mmcblk0 -b 512 -v 31116290 31116290
Checking blocks 31116290 to 31116290
Checking for bad blocks (read-only test): badblocks: Invalid argument during seek
done
Pass completed, 0 bad blocks found. (0/0/0 errors)
[tom@alarm ~]$
But dd has no such problem:
[tom@alarm ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null skip=31116287
1+0 records in
1+0 records out
512 bytes copied, 0.0254859 s, 20.1 kB/s
[tom@alarm ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null skip=31116288
0+0 records in
0+0 records out
0 bytes copied, 0.000534631 s, 0.0 kB/s
[tom@alarm ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null skip=31116289
dd: /dev/mmcblk0: cannot skip: Invalid argument
0+0 records in
0+0 records out
0 bytes copied, 0.000737962 s, 0.0 kB/s
[tom@alarm ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null skip=31116290
dd: /dev/mmcblk0: cannot skip: Invalid argument
0+0 records in
0+0 records out
0 bytes copied, 0.000694995 s, 0.0 kB/s
[tom@alarm ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null iflag=count_bytes,skip_bytes
count=1M skip=15192M
2048+0 records in
2048+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.0612828 s, 17.1 MB/s
[tom@alarm ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null iflag=count_bytes,skip_bytes
count=1M skip=15193M
1024+0 records in
1024+0 records out
524288 bytes (524 kB, 512 KiB) copied, 0.029878 s, 17.5 MB/s
[tom@alarm ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null iflag=count_bytes,skip_bytes
count=1M skip=15194M
dd: /dev/mmcblk0: cannot skip: Invalid argument
0+0 records in
0+0 records out
0 bytes copied, 0.000814785 s, 0.0 kB/s
[tom@alarm ~]$ sudo dd if=/dev/mmcblk0 of=/dev/null iflag=count_bytes,skip_bytes
count=1M skip=15195M
dd: /dev/mmcblk0: cannot skip: Invalid argument
0+0 records in
0+0 records out
0 bytes copied, 0.000700151 s, 0.0 kB/s
[tom@alarm ~]$
In any case, if you want to check whether a particular block is bad and/or compare the result of badblocks and dd, it's best that you test with the logical block size (usually 512 bytes) and do not use values that exceeds the actual size of the drive. Both pieces of information can be obtained with fdisk -l:
[tom@alarm ~]$ sudo fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 14.86 GiB, 15931539456 bytes, 31116288 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
[tom@alarm ~]$
Also make sure you count from 0 when you are specifying a specific block, and do not count one less when you are specifying numbers of blocks (like for count/skip/seek in dd)
EDIT: It's actually natural that "last block + 1" is a special case as it is valid to seek an entire drive (last block inclusive). It's just that there's no more space to read/write. But for "last block + 2" or higher, even the the seek will go past the end of the drive, hence the seek error. It might also worth noting that current badblocks doesn't exactly check what the write error is (but just return to its caller that the written length is 0): https://github.com/tytso/e2fsprogs/blob/v1.45.4/misc/badblocks.c#L443