A Parallels disk is a set of image files and one DiskDescriptor.xml that ties them together.
QEMU’s docs/interop/prl-xml.rst (read on 2026-11-14) says it “contains minimal information …
which is enough to properly work with QEMU”, and that Parallels Desktop and Parallels Cloud Server add nodes
that are not specified, which software must leave as they are. Each element below is marked documented
(QEMU’s page, or OpenVZ’s ploop lib/xml.c, also read on 2026-11-14) or observed (seen in
the three real descriptors read here, with no source that explains it).
The descriptor
One element, Parallels_disk_image, with one attribute, Version, which must be
1.0. Its three children are Disk_Parameters, StorageData and
Snapshots. (ploop writes the root as Virtuozzo_disk_image.)
Disk_Parameters
| Element | Meaning | Source |
|---|---|---|
Disk_size | The number of sectors in the disk: its desired size. | documented |
Cylinders | The number of cylinders. | documented |
Heads | The number of heads. | documented |
Sectors | Sectors per cylinder track (512-byte sectors). Heads × Sectors × Cylinders must equal Disk_size. | documented |
Padding | Must be 0. Parallels may use 1; that case is not covered, and software should not open or create such disks. | documented |
Max_delta_size | Read by ploop; written when set. No description. | documented (name only) |
Encryption | ploop reads Encryption/KeyId, the key identifier of an encrypted disk. Parallels writes the children Engine (a GUID; all zeros in the files read), Data and Salt (empty). | KeyId documented (name only); the rest observed |
PhysicalSectorSize, LogicSectorSize | Observed 4096 and 512. Every number in the image format counts 512-byte sectors. | observed |
UID | A GUID of the disk (different from the image GUIDs and from the disk’s Uuid in config.pvs). | observed |
Name | A name for the disk: the bundle name plus " SSD" (observed). | observed |
Miscellaneous | Observed children: CompatLevel (level2; the same as CompatLevel of the disk in config.pvs), Bootable, ChangeState, SuspendState, ShutdownState, GuestToolsVersion, FragmentationRatio (such as :blocksTotal=15320:contigGroups=224), and the counters DupBlocksCnt, CorruptBlocksCnt, UnrefBlocksCnt, OutOfDiskBlocksCnt, BatOverlapBlocksCnt, BlocksCnt, TruncatedBlocksCnt, ReferencedBlocksCnt (all 0 in the files read; the names suggest the checks of a repair tool). The meaning of the values is not published; a Fedora disk’s blocksTotal was 7,868 where its .hds held 7,857 clusters, so it is not simply the cluster count. | observed |
StorageData
A Storage element for each part of the disk. More than one is a split image, where each
storage covers a range of the disk; the specification does not cover split images and ploop refuses them.
| Element | Meaning | Source |
|---|---|---|
Start | The first sector of the storage: 0 when the disk is not split. | documented |
End | The sector after the last one: Disk_size when the disk is not split. | documented |
Blocksize | The cluster size in sectors. The cluster size of every Compressed image in the disk must equal it (it is the tracks field of the image’s header). | documented |
Preallocated | ploop: 0 or 1; 1 is an expanding image that was preallocated, and is not compatible with a Plain image. | documented (ploop) |
Image (several) | One for each image: the root, and every snapshot overlay. Children below. | documented |
Volume | ploop: Parent, SnapshotGUID and ReadOnly, for a volume of ploop’s own snapshot stack. | documented (ploop; name only) |
| Image child | Meaning |
|---|---|
GUID | The image’s identifier, a UUID in curly brackets, like {12345678-9abc-def1-2345-6789abcdef12}. The Snapshots element refers to it. |
Type | Plain for a raw file, Compressed for an expanding disk. The root image can be either; overlays must be expanding. |
File | The path of the image file, relative to DiskDescriptor.xml or absolute. Every real descriptor read here names the file <bundle name>.hdd.0.{GUID}.hds, in the same folder. |
Snapshots
The snapshot tree. Each Shot has a GUID, the GUID of an image, and a
ParentGUID, the image it sits on. A reader walks from child to parent through
ParentGUID. The root snapshot’s parent is {00000000-0000-0000-0000-000000000000}, and there
should be only one root. An overlay holds only the clusters that differ from its parent; its other BAT entries
are 0, and the cluster then comes from the parent.
- The top snapshot is the overlay the guest writes to; all other images are opened read-only. It is named by the optional
child
TopGUIDofSnapshots, or, when there is none, by the predefined GUID{5fbaabe3-6958-40ff-92a7-860e329aab41}. WhenTopGUIDis given, that predefined GUID is just an ordinary GUID. All three real descriptors read here use the predefined GUID for their single image. BackupID,{704718e1-2314-44c8-9087-d78ed36b0f4e}, is used by Parallels and some third-party software for backup. QEMU treats an image with it as usual; it is not recommended for new disks, and the top snapshot cannot have it.- ploop also reads the optional markers
Temporary,TemporaryZeroandTemporaryZeroSwapinside aShot. - QEMU’s page also mentions an auxiliary file,
Snapshot.xml(singular), that stores optional snapshot information and does not influence opening, reading or writing. Its contents are not given there, and none of the real bundles read has one.
Rules for a valid descriptor
- The root is
Parallels_disk_image, withVersion="1.0". Heads × Sectors × Cylinders = Disk_size, andPaddingis 0.- The disk has one Storage (not split),
Start0 andEndequal toDisk_size. - The images of the Storage include one root image and any overlays; overlays are Compressed; every Compressed image’s cluster size equals
Blocksize. - The snapshots have one root (parent all zeros), every other parent is an existing snapshot, each snapshot has an image, and the top snapshot exists.
The .hdd bundle
On a Mac the folder NAME.hdd is a bundle that Finder shows as one item. Observed in the three bundles read
(an Ubuntu and a Fedora ARM64 machine, and a macOS guest, all made by Parallels Desktop):
| Member | What it is | Source |
|---|---|---|
DiskDescriptor.xml | The descriptor above. | documented (QEMU) |
DiskDescriptor.xml.Backup | A copy; the same size as the descriptor in all three bundles. | observed |
NAME.hdd.0.{GUID}.hds | The image: the file the descriptor’s File names. For a snapshot chain, one such file for each image. | documented (QEMU); the name pattern observed |
NAME.hdd (a file) | An empty file with the bundle’s own name, inside the folder. | observed: 0 bytes |
NAME.hdd.drh | A small binary file (19,568 and 19,712 bytes) beside the image in the two Linux bundles, absent from the macOS one. It begins with 8-byte little-endian numbers (0, 0x22, 0x7FFFFDF, 0x21, 2, 0x20, 0x800, 0x44, …). No source describes it. | observed; undocumented |
A Plain image, observed
The disk of the macOS guest has Type Plain, Blocksize 2,048 and a 128 GiB Disk_size of 268,435,456 sectors
(the file is 137,438,953,472 bytes: exactly the virtual size, and sparse on disk). It has no header: its first sector is all zeros, and
bytes 512 to 519 read EFI PART, a GPT header at the second sector. A Plain image is therefore read as any raw disk
(.img).
Sources: QEMU docs/interop/prl-xml.rst and parallels.rst (master, read 2026-11-14); OpenVZ ploop
lib/xml.c (master, read 2026-11-14); three real bundles on the owner’s Mac, read only (the disk images by byte ranges).