MacBook M4 2025 Migration Log
Summary
This document chronicles the migration from an Intel x86_64 MacBook to an Apple Silicon M4 MacBook (arm64) using macOS Migration Assistant. The migration revealed several architecture-dependent issues and provided valuable insights for improving the dotfiles bootstrap process.
Key Statistics:
- Migration time: ~1 hour
- Architecture: Intel x86_64 → Apple Silicon arm64
- Major issues: 7 (PAM/sudo, bootstrap script, broken symlinks, architecture mismatches, Homebrew dual-install, Docker, cache incompatibility)
- Final state: 100% native arm64 applications, zero Rosetta 2 dependencies, ~121MB of x86_64 files removed
Phase 1: Pre-Migration & Initial Setup
Migration Assistant Transfer
- Used macOS Migration Assistant to transfer all data from Intel MacBook
- Duration: Approximately 1 hour
- A few non-essential documents failed to transfer
- Migration Assistant prompted to update the source laptop to avoid issues
- Problem: 2020 Intel Mac was not supported for macOS 26 update
- Proceeded anyway without apparent consequences
Initial System Configuration
After first boot on the new MacBook:
Apple Wallet Cards
- System prompted to add cards from Apple Wallet
- Issue: None of the cards were able to be verified
- Status: Unresolved in this session
Application Permissions Required manual permission grants for:
- BetterTouchTool (Accessibility, Screen Recording)
- Logi Options++ (Accessibility)
- Karabiner (Observer/Grader Input permissions)
Account Setup
- Added Google account as Internet Account for email
- Bitwarden app and credentials transferred seamlessly
- ChatGPT extension for Siri required re-enabling and sign-in
- Quick Look extensions (Windows and Xcode) required manual enabling
Phase 2: Bootstrap Script Issues
Issue 1: PAM Initialization Error
Attempted to run the dotfiles startup script, which started Nix installation.
Error:
sudo: unable to initialize PAM: Undefined error: 0
Root Cause:
The Intel Mac had a custom PAM configuration at /etc/pam.d/sudo that included:
auth include sudo_local
auth sufficient pam_tid.so
auth sufficient pam_smartcard.so
auth sufficient pam_smartcard.so
auth required pam_opendirectory.so
account required pam_permit.so
password required pam_deny.so
session required pam_permit.so
The sudo_local file referenced pam_reattach.so which was compiled for x86_64 and incompatible with arm64.
Context:
The PAM modification was needed to enable Touch ID with tmux in the terminal. Tmux persists across user login sessions, which breaks the default PAM integration. The pam_reattach.so module fixes this by reattaching to the user login session scope.
Resolution:
- Used macOS Finder trick to gain write permissions to
/etc/pam.d/sudo:open /etc/pam.d/in terminal- Selected sudo file in Finder
- Unlocked details and granted read/write access temporarily
- Removed
sudo_localinclude from/etc/pam.d/sudo - Immediately restored read-only permissions for everyone
sudofunctionality restored
Issue 2: Pre-existing Backup Files
Error:
---- oh no! --------------------------------------------------------------------
I back up shell profile/rc scripts before I add Nix to them.
I need to back up /etc/bash.bashrc to /etc/bash.bashrc.backup-before-nix,
but the latter already exists.
Root Cause: Migration Assistant transferred old Nix backup files from the Intel Mac.
Additional Discovery:
The /etc/bash.bashrc file already contained Nix daemon initialization code (also migrated from Intel Mac).
Resolution:
sudo rm /etc/bash.bashrc.backup-before-nix
sudo rm /etc/zshrc.backup-before-nixThen manually cleaned the Nix daemon shell script from /etc/bash.bashrc and recreated a clean backup file to represent the state before Nix installation.
Issue 3: Broken Symlinks
Error:
/dev/fd/11: line 61: /Users/achhina/.config/nix/nix.conf: No such file or directory
Root Cause: Migration Assistant copied Home Manager symlinks that pointed to Nix store paths from the Intel Mac:
nix.conf: broken symbolic link to /nix/store/mihd906bd8vlm09q3w6apak7gxq0n9h3-home-manager-files/.config/nix/nix.conf
Resolution:
rm ~/.config/nix/nix.confIssue 4: Bootstrap Script Bug
Error:
Checking for conflicts with existing /Users/achhina/.config...
/dev/fd/11: line 112: conflicts[*]: unbound variable
Root Cause: Bootstrap script attempts to expand array variable without checking if it’s set.
Status: Needs fix (see Phase 2 action items)
Phase 3: Manual Dotfiles Installation
At this point, the bootstrap script had too many issues. Proceeded with manual installation.
Repository Setup
Discovery: The .git directory was already present (transferred via Migration Assistant), so no need to reinitialize.
Issue: Lost .git directory at some point during troubleshooting (likely during mv ~/.config ~/.config.backup operations).
Resolution:
git init
git remote add origin https://github.com/achhina/dotfiles.git
git fetch --all
git reset --hard origin/mainHome Manager Installation Attempt
Initial Error:
nix run home-manager/master -- switch --flake ~/.config/nix#$(scutil --get LocalHostName)
# Output: MacBook-Pro
error: flake 'path:/Users/achhina/.config/nix' does not provide attribute
'packages.aarch64-darwin.homeConfigurations."MacBook-Pro".activationPackage'Root Cause:
The flake defined homeConfigurations.achhina and homeConfigurations.default, but scutil --get LocalHostName returned "MacBook-Pro", which didn’t match any defined configuration.
Attempted Fix:
nix run home-manager/master -- switch --flake ~/.config/nix#achhinaIssue 5: Architecture Mismatch in Flake
Error:
error: Cannot build '/nix/store/aw8s03lz3ficjlh2cn998a0r8vhdh3rr--.drv'.
Reason: required system or feature not available
Required system: 'x86_64-darwin' with features {}
Current system: 'aarch64-darwin' with features {apple-virt, benchmark, big-parallel, nixos-test}
This error appeared for multiple packages:
- bordersrc.drv
- builder.pl.drv
- detex-70015.drv
- hm-modules-messages.drv
- hm-session-vars.sh.drv
- org.nix-community.home.aerospace.plist.drv
- activation-script.drv
- home-manager-generation.drv
Root Cause:
The flake was using builtins.currentSystem which doesn’t work correctly in flake context. The configuration was hardcoded for x86_64-darwin.
Resolution:
Updated flake.nix to explicitly specify the architecture:
homeConfigurations."MacBook-Pro" = mkHomeConfiguration "aarch64-darwin";Home Manager Activation
File Collision Error:
Existing file '/Users/achhina/.config/nix/nix.conf' would be clobbered
Resolution:
nix run home-manager/master -- switch --flake ~/.config/nix#$(scutil --get LocalHostName) -b backupSuccess: Home Manager activated successfully with backup of existing files.
Post-Activation: Required re-granting Accessibility permissions to:
- Aerospace
- Borders (jankyborders)
- BetterTouchTool
- Logi Options++
Issue 6: Untrusted User Warnings
Warnings during activation:
warning: ignoring untrusted substituter 'https://nix-community.cachix.org', you are not a trusted user.
warning: ignoring untrusted substituter 'https://cache.garnix.io', you are not a trusted user.
warning: ignoring the client-specified setting 'trusted-public-keys', because it is a restricted setting and you are not a trusted user
Resolution:
# Add to /etc/nix/nix.conf
echo "trusted-users = root @admin" | sudo tee -a /etc/nix/nix.conf
# Restart Nix daemon
sudo launchctl stop org.nixos.nix-daemon
sudo launchctl start org.nixos.nix-daemonPhase 4: Architecture Migration Issues
Issue 7: Cached Binaries Architecture Mismatch
Symptoms:
- Neovim plugins failing to load (fzf)
- Pre-commit gitleaks hook failing
- Various executable incompatibilities
Root Cause:
Migration Assistant transferred the ~/.cache directory containing x86_64 compiled binaries.
Resolution:
rm -rf ~/.cacheCache directories are typically regenerated on demand.
Neovim Plugin Reinstallation
After removing cache, had to reinstall all Neovim plugins:
Issue with Lazy.nvim:
- Visual highlighting all packages and pressing
Xdidn’t work - Had to visual highlight, press
x, thenIto install all
Single Plugin Failure:
markdown-preview.nvim markdown md MarkdownPreviewToggle MarkdownPreview MarkdownPreviewStop
Vim:E117: Unknown function: mkdp#util#install
Status: Plugin partially broken, needs investigation
System Settings
Keyboard Remapping:
- Manually mapped Caps Lock → Control
- Location: System Settings → Keyboard → Keyboard Shortcuts
Phase 5: Docker & Container Setup
Docker Desktop Issues
Problem 1: Docker Desktop (GUI) had CPU architecture mismatch (x86_64)
Resolution:
- Removed Intel Docker Desktop
- Installed Docker engine via Nix
- Installed Docker Desktop (arm64) from official website
- Note: Could also be installed via Homebrew
Problem 2: Container images showed amd64 emulation warnings about potential slowdowns
Resolution:
# Pull arm64 images
docker pull --platform linux/arm64 [image-name]
# Set default builder to arm64
# Note: This required Docker Desktop restartProblem 3: Default builder communication error
Resolution:
- Enabled default socket communication in Docker Desktop Advanced settings
- Verified
/var/run/docker.socksymlink points to default builder
Phase 6: PAM/Touch ID Final Fix
Complete PAM Resolution
Background:
Earlier fix temporarily disabled pam_reattach to restore sudo. Now needed to restore Touch ID functionality with arm64-compatible module.
Problem:
Original pam_reattach.so was x86_64 (Intel Homebrew at /usr/local).
Resolution:
- Install Apple Silicon Homebrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"Installed to /opt/homebrew (arm64 location)
- Install arm64 pam-reattach:
/opt/homebrew/bin/brew install pam-reattach- Update PAM configuration:
Updated
/etc/pam.d/sudo_localto point to:
/opt/homebrew/lib/pam/pam_reattach.so
- Configured Homebrew PATH in Nix:
Added to
~/.config/nix/home-manager/modules/shell.nix:
programs.zsh.profileExtra = ''
eval "$(/opt/homebrew/bin/brew shellenv)"
'';- Applied changes:
hm switchResult: Touch ID working with sudo in tmux sessions
Phase 7: Complete Intel → Apple Silicon Migration
Homebrew Dual Installation Cleanup
Discovered State:
- Intel Homebrew at
/usr/local/bin/brew(x86_64) - Apple Silicon Homebrew at
/opt/homebrew/bin/brew(arm64)
Package Migration (5 packages)
Migrated from Intel to Apple Silicon Homebrew:
pam-reattach(formula)firefoxpwa(formula)blackhole-2ch(cask)logi-options+(cask)sublime-text(cask)
Intel Homebrew Complete Removal
Cleanup process:
# Remove all packages from Intel Homebrew
/usr/local/bin/brew uninstall --force --ignore-dependencies [package]
# Remove Intel Homebrew core
sudo rm -rf /usr/local/Homebrew
# Clean up orphaned configs and data (~25MB)
sudo rm -rf /usr/local/etc
sudo rm -rf /usr/local/share
sudo rm -rf /usr/local/var
# Remove Intel-only drivers (3 copies of chromedriver, 48MB)
sudo rm -rf /usr/local/Caskroom
# Remove osxfuse and Lua modules (x86_64)Final Verification:
find /usr/local -name "*x86_64*" 2>/dev/null | wc -l
# Output: 0Result: Zero Intel Homebrew remnants
System-Wide Application Updates (9 apps)
Migrated applications from Intel to arm64 native:
- Spotify - Intel → arm64 via Homebrew
- VLC - Intel → arm64 v3.0.21 via Homebrew
- Inkscape - Intel → arm64 v1.4 via Homebrew
- OBS Studio - Intel → arm64 v32.0.1 via Homebrew
- Anki - Intel → Universal binary via Homebrew
- Google Drive - Intel → arm64 v116.0.4 via Homebrew
- JupyterLab Desktop - Intel → arm64 v4.2.5 via Homebrew
- Streamlabs Desktop - Intel → arm64 v1.19.6 via Homebrew
- Obsidian - Migrated from Homebrew to Nix (cross-platform)
Applications Removed
No arm64 support or outdated:
- VirtualBox - No Apple Silicon support (alternatives: UTM, Parallels)
- LimeChat - Old Intel IRC client (alternatives: WeeChat, Srain, web IRC)
- Fliqlo screensaver - Intel-only
- Old Python 3.8 modules - ~1,450 x86_64 files
Nix Configuration Improvements
packages.nix reorganization:
Before:
darwinPackages = [ aerospace iterm2 jankyborders keycastr obsidian ];After:
# Cross-platform GUI applications
guiApps = [ obsidian ];
# macOS-specific packages
darwinPackages = [ aerospace iterm2 jankyborders keycastr ];Key Finding: OBS Studio is NOT available in nixpkgs for macOS (Linux-only in Nix), so it correctly remains in Homebrew.
Files Modified:
/Users/achhina/.config/nix/home-manager/modules/packages.nix- Package reorganization/Users/achhina/.config/nix/home-manager/modules/shell.nix- Homebrew PATH initialization/etc/pam.d/sudo_local- arm64 pam_reattach path
Final State & Statistics
Before Migration
- 10 Intel-only apps running via Rosetta 2
- ~2,700 x86_64 binaries across system
- Dual Homebrew installation (Intel + Apple Silicon)
- sudo broken due to PAM architecture mismatch
After Migration
- 0 Intel-only apps
- 100% native arm64 applications
- Single Apple Silicon Homebrew installation
- sudo working perfectly with Touch ID
- ~121MB of x86_64 files removed
Package Management Strategy
Declarative (Nix): CLI tools, dev tools, cross-platform apps (Obsidian)
Homebrew: macOS-specific apps not available or broken in Nix (OBS, JupyterLab Desktop, firefoxpwa, blackhole-2ch audio driver, pam-reattach, Spotify, etc.)
Performance Impact
- No more Rosetta 2 translation overhead
- Better battery life (native execution uses less power)
- Faster app launch times
- Lower memory usage
- Improved thermal efficiency
Known Issues & Action Items
Bootstrap Script Needs Fixes
- [FIXED] Unbound variable error at line 112 (
conflicts[*]) - [FIXED] No broken symlink detection or cleanup
- [FIXED] No architecture detection/warning
- [FIXED] No pre-existing Nix installation backup handling
Documentation Gaps
- [FIXED] No pre-migration checklist (what to remove/clean before migration)
- [FIXED] No architecture migration guide
- [FIXED] Hostname vs username configuration strategy not documented
- [FIXED] Trusted-users Nix requirement not documented
Configuration Cleanup
- [NOT NEEDED] Legacy “default” configuration still in flake.nix (already clean)
- [DOCUMENTED] markdown-preview.nvim plugin partially broken
- Edge case during architecture migration when VimScript autoload not ready
- Workaround documented in docs/troubleshooting.md
- Cannot be systematically prevented (race condition during lazy.nvim rebuild)
Unresolved Issues
- [UNRESOLVED] Apple Wallet cards unable to be verified