---
section: 37
x-masysma-name: recover_from_4k_block_size_emulation
title: How to recover Partition Layout from unexpected 4K Block Size Emulation
date: 2025/09/21 16:26:13
lang: en-US
author: ["Linux-Fan, Ma_Sys.ma (info@masysma.net)"]
keywords: ["kb", "howto", "512e", "4ke", "sfdisk", "block", "size", "linux", "storage"]
x-masysma-version: 1.0.0
x-masysma-website: https://masysma.net/37/recover_from_4k_block_size_emulation.xhtml
x-masysma-owned: 1
x-masysma-copyright: (c) 2025 Ma_Sys.ma <info@masysma.net>.
---
Abstract
========

Typical consumer-grade hard drives today use block sizes of 4 KiB internally
and report a block size of 512 byte to the host for compatibility. This mode
of operation is called 512e for 512 byte “emulated” block size.

Partition tables use the block size to address the locations of the different
partitions on disk. Usually this is done with the 512 byte block size.
Partitioning tools ensure that partitions are aligned to larger numbers up to
1 MiB to assure compatibility with whatever native block size the HDD (or SSD)
really has.

There are external USB HDD enclosures which report the block size as 4 KiB to
the host, irrespective of what the HDD indicates. This allows very old OSes
like Windows XP to address larger drive sizes.

However, after moving the HDD to another enclosure or after moving it from the
external enclosure to become an internal drive in the PC again, this causes
issues: Newly, the OS uses the 512 byte block size reported by the HDD and
cannot successfully process the (newly all wrong) partition table on the drive
anymore.

The HDD then appears as “unformatted” to the OS.

This post is concerned with recovering from such a change i.e. to continue using
the HDD which was previously reported with 4 KiB sector size and which is newly
attached to a case that doesn't unexpectedly translate the block size or even
used as an internal HDD.

Danger
======

Please note that attempting to do any of the recovery mechanisms here can cause
the loss of all data on any of the drives attached to your computer including
those which are not actually targeted at the recovery.

This is due to the fact that after messing up the partition table, it may be
in worst case impossible to recover from the mistake. Also, specifying a wrong
device node in any of the commands may destroy data on a previously perfectly
working and accessible drive.

I put the information here down mostly for my own use. If they help you, feel
free to use them. Do not blindly follow any of the steps without knowing their
implications. Never copy & paste commands from the Internet especially not those
which are run as root!

Remember this part of the GPL (find the full text at
[web_gpl(31)](../31/web_gpl.xhtml)) which applies to this page just as well:

>   15. Disclaimer of Warranty.
>
>   THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
> APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
> HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
> OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
> THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
> IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
> ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

Approaches to Recovery
======================

There are multiple ways to approach the recovery from the mismatching block
size between partition table and HDD:

 1. Use testdisk. Set block size to 4096 (“old” value). Observe that testdisk
    identifies the partition table correctly. Recover individual files from
    inside testdisk. This approach is comparatively safe and well-suited if you
    want to recover some selected files from an unencrypted volume on the drive.
    In my case I would have been happy with this but unfortunately the data
    of interest was on a LUKS volume hence the content was not easily available
    from inside testdisk. On the other hand, with about 4.5 TiB the volume of
    interest was too large for “casual” copying around.
 2. Use testdisk. Keep block size at 512 (correct “now” value). Scan for
    partitions. Have testdisk detect the effective partition layout from the
    data contents. I tried out this method with a 6T HDD of which one large part
    was encrypted but there were two issues: First, scanning the entire HDD for
    partitions takes a very long time - I quit after half an hour or such.
    Second, the encrypted part basically containing random bytes can cause
    testdisk to wrongly identify it as multiple partitions. It may be possible
    to override the wrongly detected layout, but I did not proceed with this
    approach far enough to see if this could be viable.
 3. Use loopback devices. This allows performing the 4 KiB block size emulation
    in software. This helps identifying the partition layout and reading data
    including from encrypted LUKS volumes. The partition layout can be processed
    with tools like `sfdisk` and using some manual editing can then be restored
    on the non-emulated 512 bytes block size device to recover the partition
    table. I found parts of this approach documented in various places of the
    Internet when trying the recovery but not the complete steps. See
    Section _Use Loopback Devices_ for an end-to-end treatise of this approach.

Use Testdisk
============

Testdisk is a fantastic tool which has helped me in many situations already.
It can scan arbitrary data dumps (including device nodes) for partitions and
extract files even in event of missing file system metadata.

If you don't know about this tool already, I can only recommend learning the
basics of it.

Please see here for a general introduction to testdisk:
<https://www.cgsecurity.org/wiki/TestDisk_Step_By_Step>

Use Loopback Devices
====================

I learned about this approach from a StackExchange answer which was lowest
ranked among the ones given at the time:
<https://unix.stackexchange.com/a/722450/379262>

The idea is to use a software-based emulation of the 4 KiB sector size.
In my case, the HDD was `sdd` hence I applied this as follows:

	losetup --sector-size 4096 -f /dev/sdd

`losetup` creates a virtual copy of the drive where 4 KiB sectors are emulated
and represented by loop device (here `loop0`).

## Reading From Encrypted Volume (Optional)

Having setup a loop device, `kpartx` makes the contained partitions of the loop
device available as individual device nodes (like `loop0p1`, `loop0p2` etc.):

	kpartx -av /dev/loop0

Afterwards, they can be accessed with LUKS as needed:

	cryptsetup open /dev/mapper/loop0p3 masysma-backup
	mount -o ro /dev/mapper/masysma-backup /mnt

One can then access all the data. After completing the immediate need for
access (i.e. backing up important files), close the LUKS container as follows:

	umount /mnt
	cryptsetup close masysma-backup

Having backed up the data of interest, I proceeded to recover the partition
table using `sfdisk`

## Recover the Partition Table with SFDISK

The correct partition table (except for wrong block size that is) can be
retrieved from the loopback device:

	sfdisk -d /dev/loop0

The output in my case was as follows:

	label: gpt
	label-id: 004D8B6B-9A91-4D55-8876-273D4F8BEA05
	device: /dev/loop0
	unit: sectors
	first-lba: 6
	last-lba: 1465130640
	sector-size: 4096

	/dev/loop0p1 : start=         256, size=      262144, type=[...]
	/dev/loop0p2 : start=      262400, size=   196608000, type=[...]
	/dev/loop0p3 : start=   196870400, size=  1268260096, type=[...]

The trick to recover the partition table correctly using a 512 byte block size
is to update all of the offset and size values to account for that as follows:

 * Replace the old `sector-size` by the new size i.e. change from 4096 to 512
 * Multiply all other decimal figures (not the UUIDs of course) with
   `* 4096 / 512` i.e. * 8 to account for the larger offsets that are
   needed when using 512 byte-based addressing.
 * Replace the names of the device nodes from the loopback device with the real
   device node i.e. in my case: `loop0` -> `sdd` and `loop0p1` -> `sdd1` etc.
   I am not sure if this step is really necessary, but I wanted to be safe
   rather than sorry here.

In my case, the resulting updated layout looked as follows:

	label: gpt
	label-id: 004D8B6B-9A91-4D55-8876-273D4F8BEA05
	device: /dev/sdd
	unit: sectors
	first-lba: 48
	last-lba: 11721045120
	sector-size: 512

	/dev/sdd1 : start=        2048, size=     2097152, type=[...]
	/dev/sdd2 : start=     2099200, size=  1572864000, type=[...]
	/dev/sdd3 : start=  1574963200, size= 10146080768, type=[...]

Save the hand-edited partition table information to a text file (e.g.
`newtbl.txt`) and _double check_ that all figures are indeed computed correctly!

Remove the loopback devices as follows:

	kpartx -d /dev/loop0
	losetup -d /dev/loop0

Finally apply the correted partition table to the raw device based on 512 bytes
block sizes:

	sfdisk /dev/sdd < newtbl.txt # DANGER DANGER DANGER

Afterwards, all partitions become visible correctly again and the drive is
fully read-writable again as it should be...

Future Directions
=================

I think it is quite the bad behaviour of an external HDD enclosure to mess with
the block size reported by the HDD even if this “fixes” the 512 bytes emulated
block size to the actual 4 KiB that the HDD might be using and allows weird use
cases like a 4T external HDD on Windows XP.

The correct way for an external HDD enclosure is to behave just the same way as
if the HDD were internally installed and report the block-size as is reported
by the HDD not by the enclosure firmware.

For future buying of external HDD enclosures I like to avoid the ones with such
a translation although in practice the only way to find out seems to be
trial'n'error as the HDD enclosure manufacturers do not typically document this
“feature” if present.

See Also
========

Debian man pages:

 * [testdisk(8)](https://manpages.debian.org/trixie/testdisk/testdisk.8.en.html)
 * [sfdisk(8)](https://manpages.debian.org/trixie/fdisk/sfdisk.8.en.html)

Here are some links to other people reporting similar issues:

 * <https://forums.tomshardware.com/threads/drive-moved-from-enclosure-to-internal-shows-as-unallocated.3002691/>
 * <https://serverfault.com/questions/764271/cant-mount-sata-drives-when-moved-from-usb-enclosure-to-internal>
 * <https://superuser.com/questions/679725/how-to-correct-512-byte-sector-mbr-on-a-4096-byte-sector-disk>
 * <https://superuser.com/questions/1701475/seagate-enclosure-hdd-showing-wrong-partition-when-directly-connected-to-pc-with>
