Maintain macOS 26.x packages and updates with Homebrew and softwareupdate
Stage Apple OS updates and standard-user Homebrew upgrades with compatibility gates, Brewfile inventory, application backups, canaries, cautious cleanup, and real restore tests.
Keep managed Macs current without exposing credentials, conflating OS and package failures, or trusting inventory files instead of recoverable application data.
- macOS 26.x
- Homebrew current supported release
- Managed supported Mac Model/build, MDM, FileVault PRK, Bootstrap Token, AC power, network, storage, and application compatibility are verified.
- Supported Homebrew ownership Standard-user prefix, trusted taps, Command Line Tools, package/service owners, and state exports are known.
- External backup and real restore Time Machine plus application-native backups have restored representative data outside the source volume.
OneLiners never runs these steps or stores secrets. Review placeholders, versions, current state, and change-control requirements before using a command.
Full guide
What you will build
- A staged macOS 26.x maintenance workflow that verifies model/build, MDM, FileVault and Bootstrap Token readiness, Apple update applicability, application compatibility, external backup, controlled restart, and post-update security/application health.
- A standard-user Homebrew lifecycle with reviewed metadata, canary formula upgrades, stateful-service backups, clean-machine Brewfile validation, cautious cleanup, and a second restore-capable backup.
- The Mac reaches the exact approved Apple build with FileVault, management, security extensions, applications, networking, and backup intact.
- Homebrew changes are attributable, supported, and tested; no package tool is run with sudo and no Brewfile is misrepresented as an immutable lockfile.
- User and application data can be restored independently before and after maintenance within documented RPO/RTO.
Architecture
How the parts fit together
Apple softwareupdate supplies signed OS/firmware updates under MDM policy and may require a FileVault-aware restart. Homebrew under a standard user manages formulae, casks, taps and user launchd services in its architecture-specific prefix. A reviewed Brewfile records desired inventory but application-native exports and external Time Machine backup protect state. Canary and observation phases separate OS, package, and cleanup risk.
- Baseline and restore test prove readiness, then the exact Apple offer and vendor compatibility are reviewed.
- macOS update installs under controlled power/restart and passes encryption, management, extension, application, and backup acceptance.
- Homebrew metadata identifies candidates; one formula/cask and its service are upgraded and observed before wider rollout.
- Brewfile is tested on a clean canary, cleanup removes only reviewed artifacts, and another backup/restore proof closes maintenance.
Assumptions
- The Mac model supports the target macOS 26.x release and is supervised or otherwise managed with valid FileVault PRK and Bootstrap Token escrow.
- Critical endpoint security, VPN, system extensions, virtualization, developer tools, backup agent, and applications explicitly support the target build.
- Homebrew is installed in its supported architecture prefix and owned by the standard operator, with supported Command Line Tools and trusted taps.
- Stateful Homebrew services have official application-level export, migration, integrity, and restore procedures.
- Time Machine destination is external/network and representative restore tests can run without overwriting originals.
Key concepts
- Apple update label
- Exact applicable softwareupdate identifier including version/build/restart semantics; safer than a generic marketing version.
- Bootstrap Token
- Escrowed management token that can authorize supported software updates and Secure Token operations without exposing a user password.
- Brewfile
- Declarative list of desired Homebrew items; it is not a complete immutable lock of historical binaries or application state.
- Formula versus cask
- Formula generally installs Unix software into Homebrew prefix; cask manages macOS applications/artifacts that can have independent updater behavior.
- Canary
- Representative low-blast-radius Mac/package/service used to reveal compatibility and migration behavior before fleet rollout.
Before you copy
Values used in this guide
{{updateLabel}}Exact softwareupdate label approved for this Mac.
Example: macOS 26.2-25C56{{brewfilePath}}Protected reviewed Brewfile.
Example: /Users/Shared/Admin/Brewfile{{formulaName}}Single approved canary formula or cask token.
Example: example{{servicePort}}Expected local application listener.
Example: 8080{{serviceLogPath}}Application-owned diagnostic log path.
Example: /opt/homebrew/var/log/example.log{{serviceBinaryPath}}Stable path used by service definition.
Example: /opt/homebrew/opt/example/bin/example{{applicationPath}}Application bundle used for Gatekeeper assessment.
Example: /Applications/Example.app{{backupSourcePath}}Exact representative file path inside the completed Time Machine backup.
Example: /Volumes/.timemachine/.../2026-07-28-101500.backup/Data/project.db{{restoreTestFile}}Separate restored representative data file.
Example: /Users/test/RestoreProof/project.dbSecurity and production boundaries
- Never place account passwords, FileVault personal recovery keys, MDM bootstrap tokens, repository credentials, or backup encryption passphrases in argv, shell history, logs, screenshots, inventory fields, or this guide.
- Use a standard user for Homebrew and routine package work. Elevate only through Apple-supported workflows; do not change ownership of system paths or run Homebrew itself with sudo.
- A FileVault personal recovery key is equivalent to a device-unlock credential. Escrow it encrypted to the authorized device-management service, restrict retrieval, log access, rotate after use, and never display it as verification evidence.
- APFS local snapshots share the source storage and disappear under space pressure. Time Machine status, a mounted backup, or a successful verify operation is not enough without periodic restore tests to separate media or a recovery Mac.
Stop before continuing if
- Stop when FileVault/Bootstrap escrow, model support, compatibility, power, space, external backup, or restore evidence is missing.
- Stop when softwareupdate label/build differs or MDM deferral/authorization is being bypassed.
- Stop Homebrew work when running as root, tap/prefix/support is untrusted, dependency impact is unknown, or stateful service lacks export/restore.
- Stop cleanup until observation, post-change backup, and real restored-data/application proof pass.
decision
Define the macOS 26.x and Homebrew maintenance boundary
Inventory Mac model, Apple silicon/Intel architecture, current macOS build, device-management ownership, FileVault escrow, bootstrap token, available power/network, critical applications/extensions, Homebrew prefix, taps, formulae, casks, services, data paths, maintenance window, backup RPO/RTO, and application-level restore tests. Separate Apple OS updates from Homebrew package changes so failures remain attributable.
Why this step matters
macOS updates can change firmware, security policy, drivers, and restart state, while Homebrew changes user-space dependencies and services. Combining them destroys rollback evidence and expands the outage.
What to understand
Use Apple's current macOS 26.x build and security release approved by management, not a hard-coded assumption that every Mac sees the same offer.
Record which Homebrew services contain state; Brewfile can reinstall packages but cannot reconstruct databases, secrets, or arbitrary config.
Do not proceed with FileVault-enabled remote systems unless authorized unlock/recovery and bootstrap-token behavior are understood.
System changes
- Creates a staged update, backup, test, and recovery record.
Syntax explained
separate waves- Makes OS and package regressions attributable and allows observation between them.
Maintenance record: MacBookPro18,3; arm64; macOS 26.1 build 25B78; supervised MDM; FileVault escrow confirmed; bootstrap token escrowed; AC power; OS update wave first; Homebrew canary 48h later; Brewfile archived; PostgreSQL logical backup and Time Machine restore test passed.
Checkpoint: Checkpoint: Define the macOS 26.x and Homebrew maintenance boundary
Continue whenOwners approve exact models/builds, compatibility, application backups, FileVault recovery, Homebrew inventory, test wave, and rollback limits.
Stop whenRecovery key escrow, AC power, support status, app compatibility, backup, or real restore evidence is missing.
If this step fails
The backup completed but a real application restore fails.
Likely causeUser data, application database/config, keychain item, launch agent, or required package inventory was excluded or not portable.
tmutil latestbackupbrew bundle check --file={{brewfilePath}}Compare restored data hashes and application integrity output.
ResolutionCorrect backup/export scope and repeat an isolated restore before update approval; do not assume package reinstallation reconstructs stateful application data.
Security notes
- Run the step only from an approved administrative session, preserve the exact before/after evidence, and keep credentials, recovery keys, tokens, and private data out of commands, output, screenshots, and tickets.
- Treat a successful command as provisional until the independent verification and a real consumer or restore test pass.
Alternatives
- Rehearse the same change on an isolated canary with production-shaped policy, storage, networking, identity, and restore conditions before production.
Stop conditions
- Stop when inventory, ownership, version, capacity, identity, encryption, backup, or recovery evidence differs from the approved plan.
- Stop when an independent access or restore path is unavailable, or when the proposed command would expose a secret or irreversibly overwrite the only usable copy.
verification
Capture macOS, hardware, management, FileVault, storage, and package baseline
Record product/build/architecture, model, FileVault status without keys, device-enrollment/bootstrap-token status, free APFS capacity, pending Apple updates, Homebrew version/prefix/support configuration, outdated items, services, and diagnostics. Store the report in protected inventory rather than public logs.
Why this step matters
The baseline ties update offers and compatibility to the real model/build and shows whether encryption recovery, disk capacity, management authorization, package state, and services are ready.
What to understand
Do not print `fdesetup` recovery information. `fdesetup status` is sufficient for encryption state.
Homebrew support depends on macOS version, architecture, prefix, Command Line Tools, and configuration; preserve `brew config` with sensitive environment values redacted.
Review every `brew doctor` warning rather than treating a nonzero or warning as automatically fatal.
System changes
- Read-only inventory; softwareupdate and brew may refresh metadata only where their documented commands do so.
Syntax explained
sw_vers- Reports installed macOS product version and build.
profiles status -type bootstraptoken- Reports escrow status without revealing the token.
brew outdated --verbose- Lists installed formulae/casks with version context before change.
sw_vers; uname -m; system_profiler SPHardwareDataType | grep -E 'Model Name|Model Identifier|Chip|Processor'; fdesetup status; profiles status -type enrollment; profiles status -type bootstraptoken; df -h /; softwareupdate --list; brew --version; brew config; brew outdated --verbose; brew services list; brew doctorProductName: macOS ProductVersion: 26.1 BuildVersion: 25B78 arm64 Chip: Apple M2 Pro FileVault is On. Enrolled via DEP: Yes MDM enrollment: Yes Bootstrap Token escrowed to server: YES Software Update Tool * Label: macOS 26.2-25C56 Homebrew 4.6.0 Your system is ready to brew.
Checkpoint: Checkpoint: Capture macOS, hardware, management, FileVault, storage, and package baseline
Continue whenSupported macOS 26.x/model, MDM and escrow healthy, FileVault On, sufficient space, expected Apple offer, supported Homebrew, known services and warnings.
Stop whenRecovery/MDM status is unknown, disk is low, model/update mismatch, Homebrew is unsupported, or critical service has no owner/backup.
If this step fails
softwareupdate lists no expected macOS update.
Likely causeThe Mac is already current, update deferral/MDM policy applies, catalog/network/CDN is blocked, model is incompatible, or date/time is wrong.
sw_verssoftwareupdate --listprofiles show -type configuration | grep -i -A4 updatesystemsetup -getnetworktimeserver
ResolutionReconcile model/build and management deferrals, restore Apple update connectivity and time, then list again; never install an unverified package from a mirror.
Security notes
- Run the step only from an approved administrative session, preserve the exact before/after evidence, and keep credentials, recovery keys, tokens, and private data out of commands, output, screenshots, and tickets.
- Treat a successful command as provisional until the independent verification and a real consumer or restore test pass.
Alternatives
- Rehearse the same change on an isolated canary with production-shaped policy, storage, networking, identity, and restore conditions before production.
Stop conditions
- Stop when inventory, ownership, version, capacity, identity, encryption, backup, or recovery evidence differs from the approved plan.
- Stop when an independent access or restore path is unavailable, or when the proposed command would expose a secret or irreversibly overwrite the only usable copy.
verification
Create Brewfile and application-aware backups, then restore a sample
Dump the current Homebrew inventory to a protected Brewfile, export each stateful service using its official application method, start a Time Machine backup, and restore representative user plus application data to a separate location. Record hashes, permissions, extended attributes, and application integrity before approving updates.
Why this step matters
Brewfile records package intent but not exact historical artifacts or state. Application exports and a Time Machine restore test prove the data needed after an update actually exists.
What to understand
Store Brewfile outside transient Homebrew paths and review it for private tap names or casks that reveal internal software inventory.
Back up databases with their supported logical/physical consistency method before Time Machine; open database files alone may not be recoverable.
A same-disk APFS local snapshot is not accepted as this backup.
System changes
- Creates Brewfile, application backups, Time Machine backup, and a separate restored test copy.
Syntax explained
brew bundle dump --force- Replaces the chosen Brewfile with current package/tap/cask/service inventory after review.
tmutil startbackup --auto --block- Starts the configured backup and waits for completion; it does not expose the backup password.
Values stay on this page and are never sent or saved.
brew bundle dump --file='{{brewfilePath}}' --force; brew bundle check --file='{{brewfilePath}}'; tmutil startbackup --auto --block; tmutil latestbackup; tmutil restore '{{backupSourcePath}}' '{{restoreTestFile}}'; shasum -a 256 '{{restoreTestFile}}'; xattr -l '{{restoreTestFile}}'`brew bundle` complete! 42 Brewfile dependencies now listed. The Brewfile's dependencies are satisfied. Total number of files: 182445 Total size: 86.4 GB Backup completed successfully. /Volumes/.timemachine/.../2026-07-28-101500.backup 9e107d9d372bb6826bd81d3542a419d6... /Users/test/RestoreProof/project.db
Checkpoint: Checkpoint: Create Brewfile and application-aware backups, then restore a sample
Continue whenBrewfile parses, stateful exports exist, Time Machine copy is external/network, and representative restore matches content/metadata/application checks within RPO/RTO.
Stop whenOnly a local snapshot exists, Brewfile contains secrets, stateful service lacks export, backup fails, or restored data cannot open.
If this step fails
The backup completed but a real application restore fails.
Likely causeUser data, application database/config, keychain item, launch agent, or required package inventory was excluded or not portable.
tmutil latestbackupbrew bundle check --file={{brewfilePath}}Compare restored data hashes and application integrity output.
ResolutionCorrect backup/export scope and repeat an isolated restore before update approval; do not assume package reinstallation reconstructs stateful application data.
Security notes
- Run the step only from an approved administrative session, preserve the exact before/after evidence, and keep credentials, recovery keys, tokens, and private data out of commands, output, screenshots, and tickets.
- Treat a successful command as provisional until the independent verification and a real consumer or restore test pass.
Alternatives
- Rehearse the same change on an isolated canary with production-shaped policy, storage, networking, identity, and restore conditions before production.
Stop conditions
- Stop when inventory, ownership, version, capacity, identity, encryption, backup, or recovery evidence differs from the approved plan.
- Stop when an independent access or restore path is unavailable, or when the proposed command would expose a secret or irreversibly overwrite the only usable copy.
verification
Review the exact Apple update offer and compatibility
Refresh and list Apple-provided updates, capture label, title, version, build, size, restart requirement, and applicable deferral. Cross-check Apple's release/security notes and each critical vendor's macOS 26.x support before installation; do not scrape or install from a third-party package mirror.
Why this step matters
Apple controls applicability and may publish multiple builds or rapid security responses. The exact offered label/build and restart behavior are safer inputs than a generic version string.
What to understand
Management deferrals can intentionally hide an update; resolve policy rather than bypassing MDM.
Check VPN, endpoint security, system/network extensions, virtualization, developer toolchains, and backup agents explicitly.
A full installer is useful for recovery/canary workflows but must still come from Apple through softwareupdate.
System changes
- Queries Apple update metadata and reads management profiles; no update installation.
Syntax explained
--list- Shows updates applicable to this Mac and whether restart is required.
--list-full-installers- Shows Apple full macOS installers available for the model.
softwareupdate --list; softwareupdate --list-full-installers; profiles show -type configuration | grep -i -A6 'Software Update' || trueSoftware Update Tool Finding available software Software Update found the following new or updated software: * Label: macOS 26.2-25C56 Title: macOS 26.2, Version: 26.2, Size: 7012450KiB, Recommended: YES, Action: restart, Finding available software Software Update found the following full installers: * Title: macOS Tahoe, Version: 26.2, Size: 16894567KiB, Build: 25C56
Checkpoint: Checkpoint: Review the exact Apple update offer and compatibility
Continue whenExact label/version/build/restart and policy are documented; all critical software supports the target; canary and communication are ready.
Stop whenOffer differs, update is deferred, compatibility is unknown, backup/recovery agent is unsupported, or security owner has not approved.
If this step fails
softwareupdate lists no expected macOS update.
Likely causeThe Mac is already current, update deferral/MDM policy applies, catalog/network/CDN is blocked, model is incompatible, or date/time is wrong.
sw_verssoftwareupdate --listprofiles show -type configuration | grep -i -A4 updatesystemsetup -getnetworktimeserver
ResolutionReconcile model/build and management deferrals, restore Apple update connectivity and time, then list again; never install an unverified package from a mirror.
Security notes
- Run the step only from an approved administrative session, preserve the exact before/after evidence, and keep credentials, recovery keys, tokens, and private data out of commands, output, screenshots, and tickets.
- Treat a successful command as provisional until the independent verification and a real consumer or restore test pass.
Alternatives
- Rehearse the same change on an isolated canary with production-shaped policy, storage, networking, identity, and restore conditions before production.
Stop conditions
- Stop when inventory, ownership, version, capacity, identity, encryption, backup, or recovery evidence differs from the approved plan.
- Stop when an independent access or restore path is unavailable, or when the proposed command would expose a secret or irreversibly overwrite the only usable copy.
command
Install the approved macOS update with explicit restart control
Quiesce stateful applications, stop Homebrew services through their owners, connect AC power and reliable network, keep local or approved remote recovery available, then install the exact approved update label. Schedule restart intentionally and never pass a user password through stdin or argv.
Why this step matters
The update can replace OS, firmware, recovery components, and trigger FileVault-aware reboot behavior. Explicit label and maintenance controls avoid installing unrelated packages and losing state.
What to understand
The command must run interactively in the approved admin context. Do not use `--stdinpass` or automation that exposes a password.
Remote-only systems need a tested macOS 26 FileVault unlock design or staffed console; do not assume SSH survives preboot.
Monitor MDM and local console through multiple restarts and allow installation to finish; forced power-off can damage the update.
System changes
- Downloads and installs the selected Apple-signed macOS update and restarts the Mac, potentially updating firmware/recoveryOS.
Syntax explained
--install label- Installs only the reviewed applicable update label.
--restart- Allows the required restart after preparation; maintenance owner must expect connectivity loss.
--verbose- Prints progress suitable for the controlled console without secrets.
Values stay on this page and are never sent or saved.
softwareupdate --install '{{updateLabel}}' --restart --verboseSoftware Update Tool Finding available software Downloaded macOS 26.2 Preparing macOS 26.2 Prepared macOS 26.2 Installing: 20.00% Installing: 60.00% Installing: 100.00% Done with macOS 26.2 Restarting...
Checkpoint: Checkpoint: Install the approved macOS update with explicit restart control
Continue whenUpdate reaches Done, Mac restarts and returns to login/MDM, FileVault unlock succeeds through normal approved path, and no install error remains.
Stop whenAC/network fails, recovery is unavailable, wrong label appears, installer errors, or an operator proposes forced shutdown during firmware/update work.
If this step fails
The Mac does not return after an update restart.
Likely causeFirmware/OS install is incomplete, FileVault unlock or Bootstrap Token is unavailable, network changed, or a security tool blocks boot.
Check MDM inventory and last check-in without exposing recovery data.Use local console/recoveryOS and Apple diagnostics.Review update and panic logs after recovery.
ResolutionUse Apple-supported recovery and the escrowed PRK only through authorized custody; do not erase until restore readiness and data ownership are confirmed.
Security notes
- Run the step only from an approved administrative session, preserve the exact before/after evidence, and keep credentials, recovery keys, tokens, and private data out of commands, output, screenshots, and tickets.
- Treat a successful command as provisional until the independent verification and a real consumer or restore test pass.
Alternatives
- Rehearse the same change on an isolated canary with production-shaped policy, storage, networking, identity, and restore conditions before production.
Stop conditions
- Do not begin until backup restore, FileVault escrow, bootstrap-token status, AC power, console/recovery, compatibility, and owner quiescing are confirmed.
- If installation stalls, preserve power and use Apple-supported diagnostics/recovery rather than deleting installer state blindly.
verification
Validate build, encryption, management, security, and applications
After every restart, confirm target version/build, FileVault On, MDM and bootstrap-token escrow, APFS/free space, network/DNS/time, security tools/extensions, backup agent, and each critical application. Compare with baseline and test one allowed plus denied security path.
Why this step matters
A login screen or matching version does not prove FileVault, management trust, extensions, networking, backup, and applications survived the update.
What to understand
Test endpoint security/VPN filters and system extensions because approval or compatibility changes can silently reduce protection.
Verify a new Time Machine backup after the update and retain the pre-update copy according to rollback policy.
Capture panic, installer, and application logs before cleanup when behavior differs.
System changes
- Read-only validation plus normal application acceptance; may trigger monitoring and post-update backup separately.
Syntax explained
BuildVersion- Distinguishes releases that share a marketing version.
systemextensionsctl list- Shows activated/waiting/terminated system extensions after update.
sw_vers; fdesetup status; profiles status -type enrollment; profiles status -type bootstraptoken; diskutil apfs list; systemextensionsctl list; softwareupdate --list; log show --last 30m --predicate 'process == "softwareupdated"' --style compact | tail -n 40ProductName: macOS ProductVersion: 26.2 BuildVersion: 25C56 FileVault is On. Enrolled via DEP: Yes MDM enrollment: Yes Bootstrap Token escrowed to server: YES Software Update Tool No new software available.
Checkpoint: Checkpoint: Validate build, encryption, management, security, and applications
Continue whenExact target build, FileVault/MDM/bootstrap healthy, network/security/apps pass, no pending update/error, and post-update backup starts.
Stop whenEncryption/escrow changes, management check-in fails, security extension is inactive, app data differs, or unexpected update remains.
If this step fails
An application or extension is incompatible after macOS update.
Likely causeThe vendor does not support macOS 26.x/build, a system extension needs approval, architecture/Rosetta changes, or the app bundled an obsolete dependency.
system_profiler SPApplicationsDataTypesystemextensionsctl listspctl --assess --verbose {{applicationPath}}arch
ResolutionQuarantine the application change, update through the official vendor/Homebrew cask path, and restore application data or the Mac from tested backup if no supported forward fix exists.
Security notes
- Run the step only from an approved administrative session, preserve the exact before/after evidence, and keep credentials, recovery keys, tokens, and private data out of commands, output, screenshots, and tickets.
- Treat a successful command as provisional until the independent verification and a real consumer or restore test pass.
Alternatives
- Rehearse the same change on an isolated canary with production-shaped policy, storage, networking, identity, and restore conditions before production.
Stop conditions
- Stop when inventory, ownership, version, capacity, identity, encryption, backup, or recovery evidence differs from the approved plan.
- Stop when an independent access or restore path is unavailable, or when the proposed command would expose a secret or irreversibly overwrite the only usable copy.
verification
Refresh Homebrew metadata and review the candidate set
After the OS observation window, run Homebrew as its owning standard user, update metadata, inspect support configuration and diagnostics, list outdated formulae/casks, dependency trees, pinned items, services, and cleanup candidates. Approve a small canary set rather than immediately upgrading everything.
Why this step matters
Metadata and diagnostics expose support, tap, dependency, service, and cleanup consequences before package mutation. Homebrew auto-update behavior must not substitute for change review.
What to understand
Pinned formulae can still be upgraded when dependencies require it; record the reason and test the dependency graph.
Cask applications may also self-update outside Homebrew, so inventory actual application versions.
`brew cleanup --dry-run` is review only. Old kegs are not a reliable rollback store.
System changes
- Updates Homebrew/tap metadata; all other commands inspect package/service/cleanup state.
Syntax explained
brew update- Updates Homebrew and tap metadata, not installed formula versions.
brew outdated --verbose- Shows installed and available versions for review.
brew cleanup --dry-run- Lists candidates without deleting them.
brew update; brew config; brew doctor; brew outdated --verbose; brew list --pinned; brew services list; brew cleanup --dry-runUpdated 2 taps (homebrew/core and homebrew/cask). ==> Outdated Formulae jq (1.7.1) < 1.8.0 openssl@3 (3.5.1) < 3.5.2 ==> Outdated Casks visual-studio-code (1.103.0) != 1.104.1 Your system is ready to brew. Would remove: /opt/homebrew/Cellar/jq/1.7.1 (20 files, 1.3MB)
Checkpoint: Checkpoint: Refresh Homebrew metadata and review the candidate set
Continue whenSupported config, understood doctor warnings, reviewed outdated/dependency/service/pin/cleanup inventory, and approved canary package set.
Stop whenHomebrew is run as root, unsupported prefix/OS appears, tap is untrusted, service data lacks backup, or dependency impact is unknown.
If this step fails
brew update fails to fetch metadata.
Likely causeGitHub/network/DNS/proxy is unavailable, repository ownership is wrong, a tap is broken, or the Homebrew installation is unsupported.
brew configbrew doctorbrew tapgit -C "$(brew --repository)" status --short
ResolutionCorrect supported network and ownership without sudo/chowning arbitrary system paths, remove or repair only the offending tap, and preserve the Brewfile.
Security notes
- Run the step only from an approved administrative session, preserve the exact before/after evidence, and keep credentials, recovery keys, tokens, and private data out of commands, output, screenshots, and tickets.
- Treat a successful command as provisional until the independent verification and a real consumer or restore test pass.
Alternatives
- Rehearse the same change on an isolated canary with production-shaped policy, storage, networking, identity, and restore conditions before production.
Stop conditions
- Stop when inventory, ownership, version, capacity, identity, encryption, backup, or recovery evidence differs from the approved plan.
- Stop when an independent access or restore path is unavailable, or when the proposed command would expose a secret or irreversibly overwrite the only usable copy.
command
Upgrade one approved formula or cask and validate dependents
Stop the owned service if required, upgrade the exact reviewed formula/cask, inspect linked version and dependencies, run application config migration/checks, restart, verify port/process and a real request, then observe before expanding the batch.
Why this step matters
A single canary limits dependency and migration blast radius. Service Running and a listener are intermediate signals; the owner must still test configuration, data, protocol, and denied exposure.
What to understand
Never assume Homebrew can downgrade to the previous bottle; maintain application-native backup and a supported forward/restore plan.
Use `brew services` only for services intended to run in that user context; system-wide daemons need a separately reviewed launch design.
Verify the listener binds only to approved addresses and test authentication/TLS/data integrity.
System changes
- Upgrades one formula/cask and may migrate/restart its user launchd service.
Syntax explained
brew upgrade formula- Limits mutation to the named package plus required dependencies.
brew services info- Shows launchd service state, user, file, and exit information.
lsof LISTEN- Confirms actual network binding after restart.
Values stay on this page and are never sent or saved.
brew upgrade {{formulaName}}; brew info {{formulaName}}; brew deps --installed {{formulaName}}; brew services restart {{formulaName}}; brew services info {{formulaName}}; lsof -nP -iTCP:{{servicePort}} -sTCP:LISTEN==> Upgrading 1 outdated package: example 1.4.2 -> 1.5.0 ==> Pouring example--1.5.0.arm64_tahoe.bottle.tar.gz 🍺 /opt/homebrew/Cellar/example/1.5.0: 42 files, 8.1MB Successfully restarted `example` (label: homebrew.mxcl.example) example (homebrew.mxcl.example) Running: ✔ User: operator COMMAND PID USER FD TYPE NAME example 481 operator 10u IPv4 TCP 127.0.0.1:8080 (LISTEN)
Checkpoint: Checkpoint: Upgrade one approved formula or cask and validate dependents
Continue whenNamed package is supported target version, dependencies healthy, service/app/data checks pass, and listener/security match baseline.
Stop whenUnexpected dependency upgrades, migration error, data mismatch, public listener, failed auth/TLS, or unsupported bottle/build appears.
If this step fails
A service managed by Homebrew does not start after upgrade.
Likely causeConfig syntax changed, data migration is required, launchd plist points to another prefix, port is occupied, or file ownership is wrong.
brew services listbrew services info {{formulaName}}lsof -nP -iTCP:{{servicePort}} -sTCP:LISTENtail -n 100 {{serviceLogPath}}
ResolutionStop the service, preserve data/config, run the application's documented migration or restore, then start and verify locally before exposing it.
Security notes
- Run the step only from an approved administrative session, preserve the exact before/after evidence, and keep credentials, recovery keys, tokens, and private data out of commands, output, screenshots, and tickets.
- Treat a successful command as provisional until the independent verification and a real consumer or restore test pass.
Alternatives
- Rehearse the same change on an isolated canary with production-shaped policy, storage, networking, identity, and restore conditions before production.
Stop conditions
- Stop when inventory, ownership, version, capacity, identity, encryption, backup, or recovery evidence differs from the approved plan.
- Stop when an independent access or restore path is unavailable, or when the proposed command would expose a secret or irreversibly overwrite the only usable copy.
verification
Validate the reviewed Brewfile on a clean canary
Review Brewfile for intended taps, formulae, casks, app-store entries, and services without secrets; on a clean compatible canary use check then install with no broad upgrade. Compare resulting inventory and execute service/application restore tests before treating the file as rebuild documentation.
Why this step matters
A clean canary proves syntax, availability, architecture, taps, and declared services better than checking the source Mac where every dependency already exists.
What to understand
`--no-upgrade` avoids broad mutation during reconstruction, but installing a missing formula can still install or update dependencies as required.
Brewfile is declarative and not an immutable version lock; record versions and use supported artifact controls where exact reproduction matters.
Restore application configuration/data separately and test it; package presence alone is not service recovery.
System changes
- Installs missing Brewfile dependencies on a clean canary without intentionally upgrading all existing dependencies.
Syntax explained
bundle check- Reports whether declared dependencies are satisfied without installing them.
--no-upgrade- Avoids the normal bundle behavior of upgrading outdated declared packages where possible.
--file- Uses the reviewed explicit Brewfile rather than an accidental current-directory file.
Values stay on this page and are never sent or saved.
brew bundle check --file={{brewfilePath}}; brew bundle install --no-upgrade --file={{brewfilePath}}; brew bundle check --file={{brewfilePath}}; brew bundle list --file={{brewfilePath}}The Brewfile's dependencies are not satisfied. Installing jq Using visual-studio-code `brew bundle` complete! 1 Brewfile dependency now installed. The Brewfile's dependencies are satisfied. jq visual-studio-code
Checkpoint: Checkpoint: Validate the reviewed Brewfile on a clean canary
Continue whenClean canary satisfies Brewfile, inventory matches intent, no secret/private credential leaks, and restored applications/services pass acceptance.
Stop whenUntrusted tap, removed cask, architecture mismatch, unexpected upgrade, secret in file, or stateful application cannot restore.
If this step fails
brew bundle check reports unsatisfied dependencies.
Likely causeThe Brewfile is stale, the host uses a different architecture/tap, a cask was renamed/removed, or required credentials/private taps are unavailable.
brew bundle check --file={{brewfilePath}}brew bundle list --file={{brewfilePath}}brew configbrew tap
ResolutionUpdate the reviewed Brewfile intentionally, keep private tap credentials in the secret broker, and test `brew bundle install --no-upgrade` on a clean canary.
Security notes
- Run the step only from an approved administrative session, preserve the exact before/after evidence, and keep credentials, recovery keys, tokens, and private data out of commands, output, screenshots, and tickets.
- Treat a successful command as provisional until the independent verification and a real consumer or restore test pass.
Alternatives
- Rehearse the same change on an isolated canary with production-shaped policy, storage, networking, identity, and restore conditions before production.
Stop conditions
- Stop when inventory, ownership, version, capacity, identity, encryption, backup, or recovery evidence differs from the approved plan.
- Stop when an independent access or restore path is unavailable, or when the proposed command would expose a secret or irreversibly overwrite the only usable copy.
command
Clean only reviewed artifacts and close with another restore-capable backup
After the observation window and confirmed application backups, rerun cleanup dry-run, review every keg/cache candidate and active service reference, clean only the approved named package or general set, run doctor and bundle check, then create a fresh Time Machine backup and repeat a small restore sample.
Why this step matters
Cleanup is destructive and Homebrew does not promise old kegs as rollback. Waiting through observation and proving backup/restore before deletion protects service recovery.
What to understand
Do not use `--prune=all` casually; cache can support offline rebuild and old artifacts may still be under incident review.
Confirm no launchd plist, script, or process references the versioned Cellar path.
Close the change only after post-maintenance backup and a representative restored file/application check.
System changes
- Deletes reviewed old Homebrew artifacts and creates a new Time Machine backup.
Syntax explained
cleanup --dry-run formula- Scopes preview to the named package before deletion.
cleanup formula- Removes old versions/caches for that package according to Homebrew policy.
Values stay on this page and are never sent or saved.
brew cleanup --dry-run {{formulaName}}; brew cleanup {{formulaName}}; brew doctor; brew bundle check --file={{brewfilePath}}; tmutil startbackup --auto --block; tmutil latestbackupWould remove: /opt/homebrew/Cellar/example/1.4.2 (42 files, 8.0MB) Removing: /opt/homebrew/Cellar/example/1.4.2... (42 files, 8.0MB) Your system is ready to brew. The Brewfile's dependencies are satisfied. Backup completed successfully. /Volumes/.timemachine/.../2026-07-28-184500.backup
Checkpoint: Checkpoint: Clean only reviewed artifacts and close with another restore-capable backup
Continue whenOnly reviewed artifacts removed, active services use current stable paths, doctor/bundle checks pass, and post-change backup plus restore proof are current.
Stop whenA process references old Cellar, rollback depends on old keg, cleanup list differs, doctor regresses, or backup/restore fails.
If this step fails
brew cleanup would remove a version still used by a service.
Likely causeThe service points into a versioned Cellar path, no stable opt symlink is used, or rollback relied on old kegs that Homebrew does not promise to retain.
brew cleanup --dry-runbrew services listreadlink {{serviceBinaryPath}}lsof | grep '/Cellar/'
ResolutionRepair service references to supported stable paths or vendor migration, preserve application backups, and do not use old Cellar content as the rollback plan.
Security notes
- Run the step only from an approved administrative session, preserve the exact before/after evidence, and keep credentials, recovery keys, tokens, and private data out of commands, output, screenshots, and tickets.
- Treat a successful command as provisional until the independent verification and a real consumer or restore test pass.
Alternatives
- Rehearse the same change on an isolated canary with production-shaped policy, storage, networking, identity, and restore conditions before production.
Stop conditions
- Stop when inventory, ownership, version, capacity, identity, encryption, backup, or recovery evidence differs from the approved plan.
- Stop when an independent access or restore path is unavailable, or when the proposed command would expose a secret or irreversibly overwrite the only usable copy.
Finish line
Verification checklist
sw_vers; fdesetup status; profiles status -type enrollment; profiles status -type bootstraptokenExact target build, FileVault On, MDM enrolled, Bootstrap Token escrowed.brew doctor; brew bundle check --file={{brewfilePath}}; brew services listWarnings understood, inventory satisfied, owned services healthy.tmutil latestbackup; shasum -a 256 {{restoreTestFile}}; xattr -l {{restoreTestFile}}External post-change backup exists and restored application data/content/metadata passes.Recovery guidance
Common problems and safe checks
softwareupdate lists no expected macOS update.
Likely causeThe Mac is already current, update deferral/MDM policy applies, catalog/network/CDN is blocked, model is incompatible, or date/time is wrong.
sw_verssoftwareupdate --listprofiles show -type configuration | grep -i -A4 updatesystemsetup -getnetworktimeserver
ResolutionReconcile model/build and management deferrals, restore Apple update connectivity and time, then list again; never install an unverified package from a mirror.
A macOS update downloads but fails to prepare.
Likely causeFree space is insufficient, installer is damaged, volume/APFS health is poor, power is unavailable, or background management conflicts.
df -h /diskutil apfs listsoftwareupdate --listlog show --last 1h --predicate 'process == "softwareupdated"'
ResolutionPreserve logs, free space through approved cleanup, run Disk Utility First Aid from the supported context if indicated, redownload, and keep the tested backup.
The Mac does not return after an update restart.
Likely causeFirmware/OS install is incomplete, FileVault unlock or Bootstrap Token is unavailable, network changed, or a security tool blocks boot.
Check MDM inventory and last check-in without exposing recovery data.Use local console/recoveryOS and Apple diagnostics.Review update and panic logs after recovery.
ResolutionUse Apple-supported recovery and the escrowed PRK only through authorized custody; do not erase until restore readiness and data ownership are confirmed.
An application or extension is incompatible after macOS update.
Likely causeThe vendor does not support macOS 26.x/build, a system extension needs approval, architecture/Rosetta changes, or the app bundled an obsolete dependency.
system_profiler SPApplicationsDataTypesystemextensionsctl listspctl --assess --verbose {{applicationPath}}arch
ResolutionQuarantine the application change, update through the official vendor/Homebrew cask path, and restore application data or the Mac from tested backup if no supported forward fix exists.
brew update fails to fetch metadata.
Likely causeGitHub/network/DNS/proxy is unavailable, repository ownership is wrong, a tap is broken, or the Homebrew installation is unsupported.
brew configbrew doctorbrew tapgit -C "$(brew --repository)" status --short
ResolutionCorrect supported network and ownership without sudo/chowning arbitrary system paths, remove or repair only the offending tap, and preserve the Brewfile.
brew upgrade fails while building or pouring a bottle.
Likely causeThe formula is unsupported on this macOS/architecture, developer tools are stale, a dependency conflicts, disk is full, or the bottle checksum/download failed.
brew configbrew doctorbrew info {{formulaName}}brew deps --tree {{formulaName}}df -h /
ResolutionStop broad upgrades, repair supported Command Line Tools/network/capacity, upgrade one formula on a canary, and use upstream-supported versions rather than forcing an old bottle.
A service managed by Homebrew does not start after upgrade.
Likely causeConfig syntax changed, data migration is required, launchd plist points to another prefix, port is occupied, or file ownership is wrong.
brew services listbrew services info {{formulaName}}lsof -nP -iTCP:{{servicePort}} -sTCP:LISTENtail -n 100 {{serviceLogPath}}
ResolutionStop the service, preserve data/config, run the application's documented migration or restore, then start and verify locally before exposing it.
brew bundle check reports unsatisfied dependencies.
Likely causeThe Brewfile is stale, the host uses a different architecture/tap, a cask was renamed/removed, or required credentials/private taps are unavailable.
brew bundle check --file={{brewfilePath}}brew bundle list --file={{brewfilePath}}brew configbrew tap
ResolutionUpdate the reviewed Brewfile intentionally, keep private tap credentials in the secret broker, and test `brew bundle install --no-upgrade` on a clean canary.
brew cleanup would remove a version still used by a service.
Likely causeThe service points into a versioned Cellar path, no stable opt symlink is used, or rollback relied on old kegs that Homebrew does not promise to retain.
brew cleanup --dry-runbrew services listreadlink {{serviceBinaryPath}}lsof | grep '/Cellar/'
ResolutionRepair service references to supported stable paths or vendor migration, preserve application backups, and do not use old Cellar content as the rollback plan.
brew doctor reports unbrewed libraries, modified files, or unsupported configuration.
Likely causeManual installs, sudo use, migrated prefixes, old taps, or local edits violate Homebrew assumptions.
brew doctorbrew configbrew list --versionsgit -C "$(brew --repository)" status --short
ResolutionReview each warning; remove or migrate only proven conflicts, restore Homebrew-owned files through supported commands, and never run a blind recursive chown.
A Brewfile rebuild installs newer versions than the source Mac.
Likely causeBrewfile records desired package names/options, not a complete immutable binary lock with historical bottle availability.
brew bundle list --file={{brewfilePath}}brew info {{formulaName}}brew config
ResolutionTreat Brewfile as declarative inventory, archive application-specific data/config and version evidence, and use a supported artifact or vendor mechanism when exact reproducibility is required.
The backup completed but a real application restore fails.
Likely causeUser data, application database/config, keychain item, launch agent, or required package inventory was excluded or not portable.
tmutil latestbackupbrew bundle check --file={{brewfilePath}}Compare restored data hashes and application integrity output.
ResolutionCorrect backup/export scope and repeat an isolated restore before update approval; do not assume package reinstallation reconstructs stateful application data.
Reference
Frequently asked questions
Can Brewfile reproduce exact versions?
Not generally. It records desired items, while current repositories may install newer versions. Protect version evidence, artifacts where supported, and application state separately.
Should Homebrew run with sudo?
No. Homebrew is designed for its owning user and warns against sudo. Elevate only for separately documented Apple/vendor system operations.
Can macOS normally be rolled back in place?
Do not assume so. Prefer a supported forward fix; otherwise erase/reinstall a supported OS and restore tested data under an approved recovery plan.
Recovery
Rollback
Prefer supported forward remediation. If macOS cannot be repaired, use Apple recovery to erase/reinstall a supported release and restore tested data; for Homebrew restore application data/config and reinstall a supported package, not an assumed old keg.
- Preserve softwareupdated, panic, Homebrew, launchd, application, backup, version, and data evidence.
- Stop/disable only the failed Homebrew service and restore its official application backup before retrying a supported package version.
- Do not rely on Brewfile or Cellar leftovers for exact downgrade; use supported vendor artifacts or rebuild on a clean compatible Mac.
- For OS failure, authorize recoveryOS/erase only after PRK custody, backup restore, data ownership, and replacement build are confirmed.
- Repeat FileVault/MDM/security/app/network/package/backup/restore acceptance after recovery.
Evidence