Skip to content
Home » The hdiutil Command on macOS: Disk Images, DMG-to-ISO, and the .cdr Gotcha

The hdiutil Command on macOS: Disk Images, DMG-to-ISO, and the .cdr Gotcha

hdiutil is the command macOS uses to build, mount, convert, and inspect disk images — .dmg, .sparseimage, .sparsebundle, and the raw .iso/.cdr family. It ships with the system at /usr/bin/hdiutil and talks to Apple’s DiskImages framework, so there is nothing to install and no separate build of it for Linux or Windows. Everything below was run on macOS 26.5.2 (build 25F84), and the output shown is what the command actually printed.

Two things worth fixing up front, because both get copied around a lot: hdiutil convert ... -format UDTO -o file.iso does not produce file.iso — it writes file.iso.cdr, which is why converting a DMG to an ISO so often ends with a file that has the wrong extension. And hdiutil has no SMB support at all: smb:// URLs and an -smbprotocol option appear nowhere in its manual. Both points are shown below rather than just asserted.

What hdiutil handles, and where diskutil takes over

Two command-line tools on macOS deal with storage, and they barely overlap. hdiutil works on disk image files — creating them, attaching them so their volumes show up under /Volumes, converting between formats, verifying checksums. diskutil works on the devices those volumes sit on — partitioning, erasing, APFS container management. The hdiutil manual points across the line itself, noting that its detach is “very similar to diskutil‘s eject.” So a question about a .dmg you downloaded or want to build is an hdiutil question; a question about a physical drive or an APFS volume is a diskutil one.

Because it’s part of the operating system rather than a portable utility, there is nothing named hdiutil to install on Linux or Windows — the DMG format on those systems is handled by unrelated tools. On a Mac it’s already present, so hdiutil: command not found almost always means the command is being typed somewhere that isn’t macOS’s Terminal.

Create a DMG from a folder

The common case is packaging a folder into a single shareable image:

hdiutil create -srcfolder ./src -volname TestVol -format UDZO app.dmg

-format UDZO gives a compressed, read-only image, which is the usual choice for handing files to someone else. One detail that dates a lot of older guides: an image created this way on current macOS is laid out as APFS inside a GPT partition scheme, not the HFS+ those guides assume. You can see it in the attach output in the next section, which reports Apple_APFS and GUID_partition_scheme rather than an HFS partition.

Mount it, then unmount it — including when it says “Resource busy”

Attaching an image verifies its checksums partition by partition, then reports the devices it created. -nobrowse keeps the volume out of Finder’s sidebar, which is what you want in a script:

$ hdiutil attach app.dmg -nobrowse
...
/dev/disk19         GUID_partition_scheme
/dev/disk19s1       Apple_APFS
/dev/disk20         EF57347C-0000-11AA-AA11-...
/dev/disk20s1       41504653-0000-11AA-AA11-...   /Volumes/TestVol

A compressed image like this expands into a nested APFS device, so attach lists several nodes rather than one — the raw image device (disk19) and the synthesized APFS device (disk20) whose volume is what mounts. The node that matters day to day is the mounted volume, /Volumes/TestVol. To unmount, hand detach the top-level image device:

hdiutil detach /dev/disk19

If something still has the volume open — a Terminal sitting inside it, a file being read — the plain form refuses and returns a non-zero status instead of ejecting. Note that it names the inner volume it couldn’t unmount (disk20), not the device node you actually passed:

$ hdiutil detach /dev/disk19
hdiutil: couldn't unmount "disk20" - Resource busy

That message, which exits with status 16, is the single most common reason an eject “doesn’t work.” Closing whatever holds the volume open is the clean fix. hdiutil detach -force /dev/disk19 unmounts it regardless, at the cost of interrupting anything that was mid-write — so it’s the fallback, not the default.

Converting a DMG to an ISO, and the .cdr you actually get

This is where the documented command and the file it leaves behind don’t match. The standard way to turn a DMG into an ISO is:

hdiutil convert app.dmg -format UDTO -o app.iso

It runs, reports that it created the file — and the file on disk is app.iso.cdr, not app.iso. hdiutil appends .cdr to a UDTO image no matter what name you pass to -o. A .cdr file is a raw disk image, identical in content to an ISO, so renaming it is the entire fix:

mv app.iso.cdr app.iso

The renamed file mounts normally. Nothing in the command’s output warns about the suffix, which is why searching for how to convert a DMG to an ISO so reliably leads to a file with the wrong extension and a mount that “fails” only because a later step is looking for app.iso.

If the goal is an ISO built from a folder rather than converted from an existing DMG, makehybrid skips the .cdr detour and writes exactly the name you ask for:

hdiutil makehybrid -iso -joliet -o out.iso ./src

That produces out.iso directly — an ISO 9660 / Joliet filesystem assembled from the folder’s contents. So the choice is: convert -format UDTO for a raw copy of an existing image (then rename the .cdr), or makehybrid when you’re building the ISO from files in the first place.

Mounting an image straight from a URL over HTTP or HTTPS

This is one of hdiutil’s genuinely unusual abilities, and it’s worth knowing even though it rarely comes up day to day: it can attach a disk image directly from an http:// or https:// address without downloading the whole file first. The DiskImages framework fetches only the parts of the image the filesystem actually reads, so you can mount a large remote image and pull a single file out of it without waiting for the entire download. The plain form puts a URL where a path would normally go:

hdiutil attach https://example.com/master.dmg

Where this earns its place is the special case, not the everyday one: grabbing a single file out of a multi-gigabyte image over the network, inspecting or verifying a published image in place before committing to the full download, or serving one master image to several machines from a single web server. Because a remote image is read-only, any change you make needs somewhere local to land — and the manual’s own example routes those writes to a shadow file, so the volume behaves as if it were writable while the image on the server is never touched:

hdiutil attach https://example.com/master.dmg -shadow /tmp/master.shadow

Two practical notes the manual calls out. Because hdiutil reads the image in many small requests rather than one long transfer, a web server with a low keep-alive ceiling — Apache’s MaxKeepAliveRequests, for instance — can stall or slow the mount, and raising it server-side is sometimes the fix. And for an older or misconfigured HTTPS server whose SSL peer can’t be verified, hdiutil has an --insecurehttp option, with an equivalent com_apple_diskimages_insecureHTTP environment variable, that turns verification off. It’s the same trade-off as any “skip the certificate check” — reasonable for a server you already trust, not something to leave on by default.

There is no SMB equivalent

The URL trick stops at HTTP and HTTPS. Guides that show hdiutil attach smb://server/share/image.dmg or an -smbprotocol option are describing something the tool doesn’t have — read end to end, hdiutil’s manual mentions smb zero times and has no such flag. Mounting an image that happens to live on an SMB share still works, just the ordinary way: mount the share first (in Finder, or with mount_smbfs), then point hdiutil attach at the file’s normal path under /Volumes. There is no smb:// mode inside hdiutil itself.

When create or attach fails with “Operation not permitted”

On recent macOS this error is usually not about the image — it’s the system’s privacy protection stopping your terminal from reading the folder you pointed at. Building a DMG from something under Desktop, Documents, or Downloads, or attaching an image stored there, can fail with Operation not permitted until the terminal app has been granted access under System Settings › Privacy & Security (Files and Folders, or Full Disk Access). Granting that access, or working from a folder macOS doesn’t guard, clears it. The reason the error text is so unhelpful on its own is that it’s a macOS permission boundary rather than anything specific to hdiutil.

For anything involving disk image files, hdiutil is the right tool and has been stable for years — the friction is almost always the .cdr suffix, a busy volume refusing to eject, or a privacy prompt, not the image being broken. When the target is a physical disk or an APFS volume rather than an image file, that’s the point where diskutil takes over.

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *