What are the "hidden sectors" in the output of the `file` command for partitions containing FAT32?

I have divided an external USB hard drive in two partitions using GParted. Both are primary partitions formatted as FAT32 and have the same size (500 GB). This is the output of file -s:

/dev/sdb1: DOS/MBR boot sector, code offset 0x58+2, OEM-ID "mkfs.fat", sectors/cluster 64, reserved sectors 64, Media descriptor 0xf8, sectors/track 63, heads 255, hidden sectors 2048, sectors 976760832 (volumes > 32 MB), FAT (32 bit), sectors/FAT 119232, reserved 0x3, serial number 0x99034dfb, label: "TOSHIBA1   "

/dev/sdb2: DOS/MBR boot sector, code offset 0x58+2, OEM-ID "mkfs.fat", sectors/cluster 64, reserved sectors 64, Media descriptor 0xf8, sectors/track 63, heads 255, hidden sectors 976762880, sectors 976760832 (volumes > 32 MB), FAT (32 bit), sectors/FAT 119232, reserved 0x1, serial number 0x96cbe274, label: "TOSHIBA2   "

In /dev/sdb2, what is hidden sectors and why is it bigger than sectors? The difference is 2048, which happens to be the value of hidden sectors for /dev/sdb1. Is this a coincidence? An error of GParted or of the file command? More importantly, is it something to be concerned about?


tl;dr

Nothing to worry about.


Wikipedia article Design of the FAT file system mentions "hidden sectors" few times and the common description of the relevant metadata entries is

Count of hidden sectors preceding the partition that contains this FAT volume. This field should always be zero on media that are not partitioned.

(with few quirks). This description seems to fit the values you observe in your particular case.


I expect Linux tools to never use this value by default. In your case the respective values 2048 and 976762880 are valid in the context of /dev/sdb, but if you consider /dev/sdb1 and /dev/sdb2 respectively then these devices are not partitioned, so in their context "hidden sectors" should be 0.

It's common to mount with like mount /dev/sdb1 /some/mountpoint, but if the partition starts at the offset of 2048 sectors of 512 bytes then you can do the same with

mount -o offset=$((2048*512)) /dev/sdb /some/mountpoint

So there is no clear indication which context is the "right" one as far as Linux is concerned. Another hint that "hidden sectors" value shouldn't matter is the fact that it embeds information that belongs to the partition table into metadata structures of the filesystem. Nowadays we tend not to mix abstraction layers like this. It's relatively easy to "desynchronize" the two pieces of information. And since the OS needs to read the partition table to find the filesystem in the first place, redundant information about the offset available only after you already know the offset is hardly useful.

Note there is another redundant information: partition tables contain partition IDs (MBR) or partition type GUIDs (GPT) which should correspond to the actual filesystems in the partitions, but may not. However this information, if coherent, is quite useful because you can learn what to expect (what OS, possible multiboot, swap partitions) by examining just the partition table. In practice sometimes this is useful for humans and sometimes for machines; especially UEFI needs to know which partition is EFI system partition. But if you tell Linux to mount /dev/sdb1 … it will try to detect the actual filesystem there rather than to examine /dev/sdb, read the partition table and use the partition ID/GUID.

I don't know what was the rationale behind "hidden sectors". Nevertheless it seems there were/are some devices that rely on this value somehow. Compare man 8 mkfs.fat:

-h number-of-hidden-sectors
Select the number of hidden sectors in the volume. Apparently some digital cameras get indigestion if you feed them a CF card without such hidden sectors, this option allows you to satisfy them. Assumes 0 if no value is given on the command line.

It appears GParted went ahead and tried to satisfy even "some digital cameras" or whatever. So this is a good thing. You absolutely don't need to redo with another tool.