How to Fix `dyld: Library not loaded: icu4c` Errors on macOS After Homebrew Operations

Encountering a dynamic linker error such as dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.##.dylib (where ## represents a version number like 62, 64,

etc.) can halt development workflows on macOS. This issue commonly arises after using the Homebrew package manager, particularly following the installation or upgrade of packages like Node.js, which might subsequently affect applications like PHP, Composer, Node.js/NPM itself, or other command-line tools. The core reason often involves a mismatch in library dependencies.

This article outlines the underlying causes of this error and presents several strategies for resolving it, based on common system configurations and package management practices seen in development environments.

Understanding the Root Cause

The error message dyld: Library not loaded: ... Reason: image not found indicates that an executable (like php or node) requires a specific version of a dynamic library (`.dylib`), in this case, a component of the International Components for Unicode (icu4c) library, but the system’s dynamic linker (`dyld`) cannot locate that exact file at the path the executable expects (/usr/local/opt/icu4c/lib/...).

This typically occurs because:

  • Dependency Updates: Homebrew might upgrade the icu4c package (often as a dependency for another package like Node.js or PostgreSQL) to a newer version.
  • Linking Issues: The application (e.g., PHP) was originally compiled and linked against an older version of icu4c. After the upgrade, the required older library file might be removed or, the symbolic link at /usr/local/opt/icu4c (which usually points to the active version in the Homebrew Cellar) now points to the newer, incompatible version.

Essentially, the application is looking for an outdated library version that is no longer readily available at the linked path, resulting in a dependency mismatch.

Resolution Strategies

Several approaches can rectify this library loading issue. The most suitable method depends on the specific system state and requirements.

Solution Matrix (Complexity & Use Cases)

Read: How to Upgrade Node.js on macOS

Solution 1: Update and Clean Up Homebrew Packages

Ensuring packages and their dependencies are up-to-date and consistent can resolve version conflicts.

Steps:

  1. Update Homebrew’s package list:
    brew update
  2. Upgrade specific conflicting packages or all packages:
    # Upgrade only icu4c
    brew upgrade icu4c
    
    # Or upgrade the package that triggered the update (e.g., node or npm)
    brew upgrade node
    brew upgrade npm
    
    # Or upgrade all outdated packages (use with caution)
    brew upgrade
    Running brew upgrade without arguments will update all installed Homebrew packages. This might update critical components like PHP or PostgreSQL to newer versions, which may not be desired in all development environments. Consider upgrading specific packages first.

    If issues arise during upgrade (e.g., non-empty directory errors), forcing the upgrade might be necessary: brew upgrade -f.

  3. Clean up old package versions:
    brew cleanup

This approach aims to align all dependencies to their latest compatible versions and remove outdated library files that might confuse. In some cases, only `brew cleanup` or `brew upgrade #package_name#` might be sufficient. If `brew` commands themselves fail, `brew update-reset` might be needed.

Troubleshooting Decision Flow

A flowchart showing the logical decision path through the various solution options

Read: How to Fix Default Ruby Version Issues on macOS with Homebrew

Solution 2: Reinstall the Affected Application

Reinstalling the application that fails (e.g., PHP, Node, PostgreSQL) forces it to re-link against the currently installed version of `icu4c`.

Steps:

# Example: Reinstall a specific PHP version
brew reinstall php@#.#

# Example: Reinstall Node.js
brew reinstall node

# Example: Reinstall NPM (often bundled with Node, but sometimes managed separately)
brew reinstall npm

# Example: Reinstall a specific PostgreSQL version
brew reinstall postgresql@##

# Example: Reinstall Yarn (if installed via Homebrew)
brew reinstall yarn

Replace `#.#` or `##` with the specific version number required (e.g., `php@7.4`, `postgresql@12`). If unsure of the version, check Homebrew’s linked version or use `echo $PATH` to find the path of the active executable.

Note: Older formulae (like PHP 7.x) may no longer be available in the main Homebrew repository.

Read: Resolving ‘xcrun: error: invalid active developer path’ for Git on macOS After Updates

Solution 3: Reinstall `icu4c` Directly

Sometimes, simply reinstalling the `icu4c` package itself can fix linking or permission issues.

brew reinstall icu4c

If this step relates to issues with Ruby gems that depend on `icu4c` (like `charlock_holmes` or potentially `vips`), reinstalling the gem afterward might be necessary:

# Example for charlock_holmes
gem uninstall charlock_holmes
gem install charlock_holmes

Which approach should be used to resolve the library loading issue

Solution 4: Switch to a Required Older `icu4c` Version (If Installed)

If the required older version of `icu4c` is still present in the Homebrew Cellar but not linked, you can switch the active link.

Steps:

  1. Identify installed versions:
    brew info icu4c
    # or
    brew list --versions icu4c
  2. Identify the version needed from the error message (e.g., `libicui18n.62.dylib` implies version 62.x).
  3. Switch the link (syntax depends on Homebrew version and whether formulae are versioned):
    # Older Homebrew command (deprecated)
    brew switch icu4c 
    
    # Newer approach using link/unlink (often for versioned formulae like icu4c@68)
    # Example assuming version 62.1 is needed and installed as icu4c:
    brew unlink icu4c # Unlink the current version first
    brew link icu4c@62.1 # Link the desired version (adjust formula name/version)

    Adjust (e.g., `62.1`) or the formula name (`icu4c@62.1`) based on availability and requirement. The latest commands might involve `unlink` then `link`.

Solution 5: Install a Specific Older `icu4c` Version via Formula URL/File

If the required older version isn’t installed, Homebrew allows installing directly from a specific historical formula file (`.rb`).

Steps:

  1. Find the URL of the raw formula file (`icu4c.rb`) for the desired version (e.g., 62.1, 64.2) from the `homebrew-core` GitHub repository history. Examples mentioned include:
    • Version 62.1: `https://raw.githubusercontent.com/Homebrew/homebrew-core/575eb4bbef683551e19f329f60456b13a558132f/Formula/icu4c.rb`
    • Version 64.2: `https://raw.githubusercontent.com/Homebrew/homebrew-core/a806a621ed3722fb580a58000fb274a2f2d86a6d/Formula/icu4c.rb`
    • Version 67.1: `https://raw.githubusercontent.com/Homebrew/homebrew-core/88b9cc789820f2f544d8d4a1053eebb044c2926c/Formula/icu4c.rb`
  2. Download the formula file:
    # Using wget
    wget #URL_of_raw_formula_file# -O icu4c-#version#.rb
    
    # Using curl
    curl #URL_of_raw_formula_file# -o icu4c-#version#.rb
  3. Reinstall using the downloaded file:
    brew reinstall ./icu4c-#version#.rb

    (Older Homebrew versions might have allowed direct installation from the URL: `brew reinstall #URL_of_raw_formula_file#`, but downloading first is generally required now).

Solution 6: Install a Specific Older `icu4c` Version via Git History Checkout

This advanced method involves checking out the formula file from Homebrew’s Git history to install an older version.

Install Older icu4c Version

Steps:

  1. Ensure you have a full clone of the `homebrew-core` tap (warning: large download ~900MB):
    brew tap homebrew/core --force
    cd $(brew --repo homebrew/core)
    # If the history is shallow, deepen it (may not always be needed):
    # git fetch --unshallow
  2. Find the commit hash associated with the desired `icu4c` version (e.g., 62.1):
    brew log icu4c
    # Look for commits mentioning the target version (e.g., 575eb4b for 62.1)
  3. Check out the specific formula file from that commit:
    git checkout #commit_hash# -- Formula/icu4c.rb
  4. Uninstall the current `icu4c` (ignoring dependencies temporarily):
    brew uninstall --ignore-dependencies icu4c
  5. Install `icu4c` using the checked-out formula:
    brew install icu4c
  6. Clean up the Git repository:
    git reset --hard HEAD
  7. (Optional) Pin the installed version to prevent accidental upgrades:
    brew pin icu4c

    (Remember to `brew unpin icu4c` if you later want to upgrade it).

This method is complex and relies on historical Git data and formula formats. Older bottles (pre-compiled binaries) might not be available, forcing a potentially lengthy source compilation. Formula formats may also change over time.

Solution 7: Compile `icu4c` from Source

If pre-built versions or formulae cause issues, compiling the required `icu4c` version from its source code is an alternative.

Steps (Example for version 62.1):

  1. Download the source code archive for the required version (e.g., from the ICU project website or GitHub releases).
    mkdir ~/sources && cd ~/sources
    wget http://download.icu-project.org/files/icu4c/62.1/icu4c-62_1-src.tgz
    # Note: URLs change; find the correct one for your version.
    tar xvzf icu4c-62_1-src.tgz
    cd icu/source
  2. Configure, build, and install:
    ./configure --prefix=/usr/local/icu4c/#version#  # Optional: install to a versioned path
    make
    sudo make install
  3. Manually create symbolic links if necessary (paths may vary):
    # Example linking into /usr/local/lib/
    ln -sf /usr/local/Cellar/icu4c/#version#/#version#/lib/*.dylib /usr/local/lib/
    # Or potentially adjust DYLD_LIBRARY_PATH (less common)

Solution 8: Reinstall Xcode Command Line Tools

Especially after a macOS upgrade, development tools can become misconfigured. Reinstalling the Xcode Command Line Tools can sometimes resolve underlying linking issues.

xcode-select --install

After installation, consider running `brew upgrade` again.

Solution 9: Uninstall Conflicting Older Packages

If the error references an old library version required by an outdated, specific version of a package (like `node@8`), uninstalling that conflicting package might resolve the issue.

# Example: Uninstalling an old Node version
brew uninstall node@8

# Example: Force uninstall node and icu4c (use carefully)
brew uninstall --ignore-dependencies node icu4c
# Followed potentially by reinstalling the needed node version:
brew install node

Solution 10: Build the Affected Application from Source

Instead of adjusting libraries for the application, rebuild the application so it links against the current libraries.

# Example for PHP 7.2
brew uninstall php@7.2
brew install --build-from-source php@7.2
# May need to force link it afterwards
brew link --force php@7.2

This ensures the application (PHP in this case) is compiled using the `icu4c` version currently managed by Homebrew.

Verification

After applying a potential solution, verify its effectiveness by running the command that previously failed. For example:

php -v
composer --version
npm -v
node -v
# Or the specific command that was triggering the error

Successful execution without the `dyld: Library not loaded` error indicates the issue is resolved.

Potential Issues and Considerations

  • `brew upgrade` Impact: Be mindful that upgrading all packages can have unintended consequences on projects relying on specific older versions.
  • Pinning Packages: Using `brew pin #package#` prevents automatic upgrades but requires manual unpinning (`brew unpin #package#`) for future updates.
  • Dependency Management: Tools like NVM (Node Version Manager) manage Node.js versions independently of Homebrew. Ensure the correct NVM version is active (`nvm list`, `nvm use #version#`).
  • Manual Intervention: Some solutions involve manual file operations (like `rm -rf` in the Cellar or manual symlinking). Exercise caution with these commands.
  • Tooling Health: Running `brew doctor` can identify other potential Homebrew configuration issues.

Conclusion

The dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n... error on macOS typically signals a broken link or version mismatch for the icu4c library, often triggered by Homebrew package management operations. Resolving it usually involves aligning the versions of applications and their dependencies.

This can be achieved through upgrading packages, reinstalling affected software or libraries, explicitly managing library versions (switching, installing older versions, compiling from source), or ensuring development toolchains like Xcode Command Line Tools are correctly configured. Selecting the appropriate strategy depends on the specific context and whether maintaining older library versions is necessary.

 

Seb da Silva

Seb brings a practical, end-user-focused perspective to the IT world, drawing from years of experience in technical support and IT consulting for small businesses. He covers a wide range of topics including Windows and Linux desktop customization, hardware reviews and troubleshooting, software comparisons, mobile device integration, and general IT best practices for home users and professionals alike. David excels at translating technical jargon into clear, easy-to-understand advice.