You provision a new Apple M-series Mac, restore your shell profile, clone your infrastructure repository, and run terraform plan or aws sts get-caller-identity. Instead of the expected output, your terminal immediately halts with: zsh: bad CPU type in executable.
This error halts productivity for Cloud Engineers and system administrators migrating to modern Apple hardware. It indicates a fundamental architecture mismatch between your installed command-line tools and the host operating system.
Here is exactly why this happens and the definitive steps to resolve it permanently.
Understanding the Root Cause: Architecture Mismatch
To understand the bad CPU type in executable macOS error, you must look at the underlying CPU architecture. Legacy Mac hardware utilized Intel processors, which are built on the x86_64 (or AMD64) instruction set. Modern Apple Silicon (M1, M2, M3, M4) utilizes the ARM64 (or aarch64) instruction set.
When you execute a binary, the macOS kernel inspects the Mach-O (Mach Object) header to determine if the binary's compiled architecture matches the CPU. If you attempt to run an x86_64 compiled binary of Terraform or the AWS CLI on an M-series Mac, the kernel rejects it.
Historically, macOS masked this transition by automatically prompting users to install Rosetta 2—Apple's dynamic binary translator. However, when executing CLI tools in a headless terminal environment, this GUI prompt is suppressed. Without Rosetta 2 present to translate the x86_64 instructions to ARM64 on the fly, the execution instantly fails.
Understanding the Terraform M1 Mac architecture requirement is critical. You now have two distinct paths forward: migrate to native ARM64 binaries (recommended for performance) or install the emulation layer (required for legacy compatibility).
The Fix: Two Paths to Resolution
Path 1: Migrate to Native ARM64 Binaries (Recommended)
Running infrastructure tools natively avoids emulation overhead and eliminates reliance on legacy translation layers. Both AWS and HashiCorp provide native ARM64 binaries.
First, verify your current system architecture by running:
uname -m
# Expected output on Apple Silicon: arm64
Installing the AWS CLI Apple Silicon Native Version
If you migrated your system from an Intel Mac, your old x86_64 AWS CLI binary likely came with it. You must remove the old installation and install the native Apple Silicon package.
Execute the following script to purge the legacy installation and install the native binary:
# 1. Locate and remove the existing x86_64 AWS CLI binaries
sudo rm -rf /usr/local/aws-cli
sudo rm -f /usr/local/bin/aws
sudo rm -f /usr/local/bin/aws_completer
# 2. Download the native ARM64 macOS pkg
curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
# 3. Install the package via the command line
sudo installer -pkg AWSCLIV2.pkg -target /
# 4. Verify the architecture
aws --version
The output should now explicitly state aarch64 or arm64 alongside the Darwin kernel version.
Installing Native ARM64 Terraform
If you use Homebrew, ensure you are using the ARM64 Homebrew installation located at /opt/homebrew, not the legacy Intel version at /usr/local/bin.
Reinstall Terraform using the native package manager:
# Uninstall the broken architecture version
brew uninstall terraform
# Tap the official HashiCorp repository and install
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
# Verify execution and architecture
terraform version
Path 2: Emulation for Legacy Tools
While native binaries are ideal, DevOps environments often require older, pinned versions of Terraform (e.g., v0.11 or v0.12) or proprietary enterprise CLI tools that have not been recompiled for ARM64. In these scenarios, native execution is impossible.
You must install Rosetta 2 terminal utilities directly from the command line to force macOS to translate the x86_64 instructions.
Execute Apple's software update utility with the Rosetta flag and automatically accept the licensing agreement to bypass the GUI prompt:
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
Once the installation completes, the bad CPU type in executable error will disappear. The macOS kernel will detect the x86_64 Mach-O header, transparently invoke Rosetta 2, translate the binary ahead-of-time (AOT), and execute the tool.
Deep Dive: Validating Your Toolchain Architecture
As a System Administrator, you should not guess what architecture your binaries are targeting. macOS provides built-in tools to inspect binaries before execution.
You can use the file command to read the executable header:
file $(which aws)
# Native output: /usr/local/bin/aws: Mach-O 64-bit executable arm64
# Legacy output: /usr/local/bin/aws: Mach-O 64-bit executable x86_64
For a deeper inspection of universal binaries (fat binaries containing both x86_64 and arm64 slices), use Apple's lipo tool:
lipo -archs $(which terraform)
# Output might be "x86_64 arm64" for universal binaries
# Output will be "arm64" for pure native binaries
If a binary is universal, the macOS kernel will automatically prioritize the native arm64 slice, ensuring optimal performance without requiring intervention.
Common Pitfalls and Edge Cases
The tfenv Architecture Trap
Many Cloud Engineers use tfenv to manage multiple versions of Terraform. If you install an older version of Terraform (prior to v1.0.11, when HashiCorp began officially publishing darwin/arm64 releases), tfenv will attempt to download the amd64 version, causing the CPU type error.
To resolve this, you must have Rosetta 2 installed (as shown in Path 2). Then, instruct tfenv to explicitly fetch the amd64 binary using environment variables:
# Force tfenv to download the x86_64 version for Rosetta translation
TFENV_ARCHITECTURE=amd64 tfenv install 0.14.11
tfenv use 0.14.11
Mixed Homebrew Installations
A frequent cause of persistent CPU type errors is running two distinct instances of Homebrew. Apple Silicon Macs isolate ARM64 Homebrew inside /opt/homebrew/ while retaining /usr/local/ for Intel-based binaries.
If your shell $PATH prepends /usr/local/bin before /opt/homebrew/bin, your terminal will continuously resolve legacy x86_64 binaries first. Verify your $PATH order in your .zshrc or .bash_profile:
# Ensure ARM64 Homebrew takes precedence
export PATH="/opt/homebrew/bin:$PATH"
Conclusion
The bad CPU type in executable error is a deterministic failure caused by executing x86_64 binaries on an ARM64 host without a translation layer. By actively auditing your toolchain, migrating to native Apple Silicon binaries for tools like the AWS CLI and modern Terraform releases, and properly deploying Rosetta 2 for legacy dependencies, you ensure a stable, high-performance infrastructure provisioning environment.