Three layers, and all three have to work
"Enable Rosetta" sounds like one switch. It's actually three independent things, each satisfied differently, each silently doing nothing if it isn't:
- Rosetta itself has to be installed on the host — a one-time
softwareupdate --install-rosetta, unrelated to Velo entirely. - The workspace's Rosetta toggle has to be on — which attaches a resource to the VM. That's all it does.
- The guest has to be told to use it — a one-time setup command run inside the Linux VM itself, covered below.
Skip any one of the three and x86_64 binaries just fail to run, the same way they would with no Rosetta involved at all — there's no distinct error pointing at which layer is missing.
What the toggle actually attaches
Turning Rosetta on for a workspace calls straight into Apple's own VZLinuxRosettaDirectoryShare API and wires the result in as a VirtioFS device tagged "rosetta" — the same kind of device this blog's device inventory post covers for shared folders, just carrying Apple's translator binary instead of a folder you picked. That's the entire effect. No package gets installed in the guest, no configuration file gets written, nothing about the guest's boot process changes.
Here's the layer-one dependency made concrete: if Rosetta isn't installed on the host, the API this device is built from reports itself unavailable, and Velo's own device-construction code returns nothing — the workspace boots exactly as it would with the toggle off, no warning at VM-creation time. Velo's separate capability-check pass does know the difference and surfaces a plain note when Rosetta isn't installed — worth checking there first if a workspace with the toggle on behaves like it's off, rather than assuming the guest-side setup below was done wrong.
Setting it up inside the guest
The share being present doesn't make the guest kernel route x86_64 binaries through it — Linux has to be told to, via binfmt_misc, the same kernel facility that lets it dispatch a script by its shebang line or a Java jar by its class-file magic bytes. Three steps, run once per workspace (or once per base image, if you seal it afterward):
- Mount the share Velo attached:
sudo mount -t virtiofs rosetta /media/rosetta(aftermkdir -pon the mount point). - Install the package that lets the kernel register a custom interpreter:
sudo apt-get install -y binfmt-supporton Ubuntu or Debian. - Register Rosetta as the handler for the x86_64 ELF magic bytes with
update-binfmts --install, pointing it at the mounted translator.
One flag in that last step is worth understanding rather than copy-pasting blind: --fix-binary yes. It tells the kernel to open the interpreter's file descriptor once, at registration time, and hold onto it — rather than re-resolving the interpreter's path on every single exec. The practical effect is that the translation keeps working even from inside a mount namespace, chroot, or container that can't itself see /media/rosetta. That detail matters more than it looks: it's the same mechanism that determines whether an x86_64 Docker container pulled inside this same guest gets fast translation or falls back to slow software emulation.
The gotcha in the other direction: when the app itself is translated
There's a second, easy-to-miss way Rosetta can be involved that has nothing to do with the guest at all. Velo Workspaces ships as a universal binary — arm64 and x86_64 slices in one app — and macOS normally launches the native slice automatically. But it's possible to end up running the x86_64 slice on an Apple Silicon Mac anyway (a Rosetta-forced launch, or occasionally a download or update that landed the wrong slice), and when that happens, the app itself is the thing under translation, checkable via sysctl.proc_translated.
Velo's own capability detection checks for exactly this, because the consequence isn't a performance hit you'd just shrug off — a whole set of Apple-Silicon-exclusive APIs stop being available to the app in that state, and Rosetta-for-Linux is one of them, alongside Windows 11 ARM guests and hibernate/restore. If Rosetta support looks unavailable on a Mac you're sure is Apple Silicon, this is worth ruling out before anything guest-side: check Activity Monitor's "Kind" column for the running app, or just reinstall from the App Store, which always serves the correct slice.
What this doesn't fix
None of the above turns a Linux guest into something that can run x86_64 software with x86_64-only dependencies — only individual, dynamically-linked binaries. The Ubuntu post's Rosetta section covers that limit concretely, including where it actually breaks. And if what's actually needed is a full x86_64 operating system rather than a handful of translated binaries inside an arm64 one, that's a different tool entirely — see can you install x86 Linux on an Apple Silicon Mac for what Rosetta does and doesn't substitute for there.
Related reading: ARM64 vs. x86-64 on Apple Silicon for how this fits alongside macOS-app Rosetta and multi-arch containers, Ubuntu on Apple Silicon for Rosetta's real-world limits, and the device inventory post for how VirtioFS devices work generally. Or download Velo Workspaces and try it yourself.