At two in the morning, the team's oldest iOS project gets moved from a local Intel Mac to a freshly provisioned cloud Mac mini M4. pod install finishes fine, but the moment xcodebuild kicks off, it dumps a wall of red errors: have architecture 'x86_64', need 'arm64'. This isn't a network hiccup or a misconfigured file — the machine simply has a different chip. Apple Silicon and Intel are two entirely different instruction sets, and an old project accumulates years of third-party libraries, scripts, and CLI tools, many of which are still stuck in the x86_64 era. Moving house isn't just copy-paste; you have to clear the architecture hurdle first.
Scenario: the first build fails on a dedicated bare-metal machine
The cloud Mac mini's M4 chip runs a native arm64 system, while your project might be hiding several kinds of "holdouts": a precompiled binary from some signing tool, a CocoaPods private source that hasn't been updated in years, or even an old CLI tool called directly from a CI script. None of this ever caused problems on your local Intel Mac — it only shows its true colors after landing on Apple Silicon hardware.
System note: this device is a dedicated bare-metal machine. Any architecture switch, Rosetta installation, or system-setting change only affects your own instance and never bleeds into a "neighbor's" environment — that's one of the reasons to pick dedicated bare metal over a shared VM.
What Rosetta 2 actually is, and when you genuinely need it
Rosetta 2 is Apple's dynamic translation layer that lets x86_64-compiled binaries run on arm64 chips, at the cost of performance. It's better suited to a "get it running first, optimize later" transitional stage, not something to rely on long-term — any dependency with an available native arm64 build should be swapped in as soon as possible.
Checking whether a dependency actually needs it
Before rushing to install anything, use two commands to see exactly which files are the "outsiders":
file /usr/local/bin/some-tool
lipo -info /usr/local/lib/libSomeSDK.a
file tells you straight away whether a binary is Mach-O 64-bit x86_64 executable or arm64; lipo -info is more precise for static libraries, since it shows whether the library is universal (containing both x86_64 and arm64 slices). If the output shows only x86_64, that item must fall back on Rosetta compatibility, or you'll need to ask the vendor for an arm64 build.
Three steps to fill the compatibility gap
Step 1: Install Rosetta
Run this once on the cloud Mac mini — it takes effect system-wide:
softwareupdate --install-rosetta --agree-to-license
Step 2: Locate every problematic dependency
Write a small loop to batch-scan the static libraries and dependency binaries under Pods/, and list out anything that isn't arm64. Save this list — it's your checklist for future upgrades:
find Pods -name "*.a" -exec sh -c 'lipo -info "$1" | grep -q arm64 || echo "$1"' _ {} \;
Step 3: Force the architecture when needed
For CLI tools that don't have an arm64 build yet, use arch to explicitly pin the architecture and route through Rosetta — don't wait for the system to auto-detect and fail:
arch -x86_64 /usr/local/bin/legacy-signing-tool --version
Diagnosing CocoaPods and Homebrew architecture conflicts
If a simulator build reports "no matching architecture slice found," odds are the Podfile hasn't excluded the arm64 simulator architecture — or, the opposite mistake, it's excluded the arm64 device architecture by accident. Add a simulator-specific exclusion rule at the end of the Podfile, and double-check the Excluded Architectures field in Xcode's build settings to make sure it isn't set backwards.
The classic Homebrew trap is mixing old and new prefixes — the native arm64 Homebrew installs to /opt/homebrew, while the x86_64 Homebrew running under Rosetta installs to /usr/local. Mixing the two brew installations often leads to dependency versions clashing with each other. It's best to keep only one and explicitly set the PATH priority in your .zshrc.
Checklist and common error reference table
| Error keyword | Likely cause | Fix |
|---|---|---|
have architecture 'x86_64', need 'arm64' |
Static library doesn't ship an arm64 slice | Confirm with lipo -info, then switch to the universal build |
Bad CPU type in executable |
CLI tool is a pure x86_64 binary | Force-run it with an arch -x86_64 prefix |
| Missing simulator slice in CocoaPods | Podfile doesn't exclude the arm64 simulator architecture | Add an EXCLUDED_ARCHS rule |
brew can't find a package |
Two Homebrew prefixes are mixed together | Keep just one, clean up PATH |
Post-migration verification: native or still riding Rosetta
A successful build doesn't mean the migration is done. You still need to confirm that the critical paths are actually running natively on arm64, not just limping along on Rosetta the whole time. Add an environment self-check line to your build script that prints the current process's architecture; if you find that the main build pipeline — not just some peripheral tool — is still relying on Rosetta long-term, that's a sign there's more room to swap in native dependencies, and it's worth putting on the next dependency-upgrade roadmap.
Frequently asked questions
Do I have to recompile every x86_64 dependency before it works?
Not immediately. Run under Rosetta 2 first to confirm the app still works, then swap in arm64 builds of each dependency one at a time instead of blocking the whole team on a full rewrite.
Will installing Rosetta 2 on my cloud Mac mini affect other users?
No. Each node is a dedicated physical machine, so architecture settings only apply to your own instance — there's no shared-VM neighbor effect.
CocoaPods can't find a simulator slice, what's wrong?
Usually the Podfile hasn't excluded the arm64 simulator architecture, or EXCLUDED_ARCHS is set backwards. Check the Excluded Architectures field in your Xcode build settings as described in this guide.
portal://order
Need one right now?
A dedicated physical Mac mini, billed by the day, ready to use in about 4 minutes from payment.