Start here: what actually fails?
Before anything else, get precise about the failure. "Command not found" or a package manager reporting nothing available is a different problem from a binary that exists but crashes or refuses to start, which is different again from a Docker pull failing to find a matching image. The error itself usually already tells you which of the four cases below you're in — the mistake is reaching for the same fix (usually "just emulate it") regardless of which one it is.
1. The package genuinely has no arm64 build
Check first whether this is real before working around it: a distro's arm64 ports repository doesn't always mirror every package available for amd64, and pulling an amd64 .deb by hand for a package that's simply missing on arm64 gets you a plain 404, not a working install. The Ubuntu post's Rosetta section covers this gap concretely, including exactly where it bites. If a native arm64 build genuinely doesn't exist, building from source is sometimes viable — but watch for hardcoded x86_64 in a project's build scripts or autotools target triples, which look like a compatibility failure but are really just a build script someone never updated for a second architecture.
2. It's one binary, not a whole ecosystem
A single, self-contained x86_64 executable — a CLI tool, a compiled binary someone handed you directly — is the case Rosetta for Linux is built for. The full setup is covered here: it translates that one binary, running natively inside an accelerated arm64 guest, and it's meaningfully faster than any of the emulation options below. It stops being the right tool the moment the binary drags in x86_64-only shared libraries or a whole dependency tree that also isn't built for arm64 — at that point you're back in case 1 or 3, not case 2.
3. It's a container image
An amd64-only Docker image is its own case with its own mechanism — QEMU emulation by default, sometimes faster if Rosetta for Linux is already set up in the same guest — covered in full here. Worth distinguishing explicitly from case 2: a container failing to find a matching architecture in its manifest is a Docker/registry problem, not something update-binfmts alone fixes, even though the same kernel facility ends up involved either way.
4. It genuinely needs a different CPU architecture
The rare, real case: software with architecture-specific assembly or SIMD intrinsics written assuming x86, an out-of-tree kernel module with no arm64 port, or a requirement to actually verify behavior on the CPU architecture your users run rather than a translated stand-in for it. None of the above helps here — that's full QEMU-based emulation of a genuinely different architecture, accepting the real performance cost that comes with it, or an actual x86_64 machine somewhere in the loop.
The triage, short version
| Symptom | Likely case | Fix |
|---|---|---|
| Package manager: nothing found | 1 — missing native build | Confirm it's really missing, then build from source or find an alternative |
| One binary won't execute | 2 — single x86_64 binary | Rosetta for Linux |
docker pull can't find your architecture | 3 — container image | amd64 image emulation |
| Needs a real x86 CPU to behave correctly | 4 — true architecture dependency | Full QEMU emulation |
Related reading: Rosetta 2 in Linux VMs, running x86 Docker images on an Apple Silicon Mac, can you install x86 Linux on an Apple Silicon Mac, and ARM64 vs. x86-64 on Apple Silicon for the broader picture this all sits inside. Or download Velo Workspaces and try it yourself.