Skip to content

brew upgrade & reinstall sometimes fail for pinned dependencies, when the pinned formula is not a dependency. #20887

@jacktose

Description

@jacktose

brew doctor output

Your system is ready to brew.

Verification

  • I ran brew update twice and am still able to reproduce my issue.
  • My "brew doctor output" above says Your system is ready to brew or a definitely unrelated Tier message.
  • This issue's title and/or description do not reference a single formula e.g. brew install wget. If they do, open an issue at https://github.com/Homebrew/homebrew-core/issues/new/choose instead.

brew config output

HOMEBREW_VERSION: 4.6.17
ORIGIN: https://github.com/Homebrew/brew
HEAD: aa278895809b4c079e560fb4fb9bf17e48cf65f1
Last commit: 2 days ago
Branch: stable
Core tap JSON: 15 Oct 18:06 UTC
HOMEBREW_PREFIX: /home/linuxbrew/.linuxbrew
HOMEBREW_CASK_OPTS: []
HOMEBREW_DISPLAY: :0
HOMEBREW_DISPLAY_INSTALL_TIMES: set
HOMEBREW_EDITOR: vim
HOMEBREW_FORBID_PACKAGES_FROM_PATHS: set
HOMEBREW_GITHUB_API_TOKEN: set
HOMEBREW_MAKE_JOBS: 20
Homebrew Ruby: 3.4.5 => /home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/vendor/portable-ruby/3.4.5/bin/ruby
CPU: 20-core 64-bit alderlake
Clang: N/A
Git: 2.43.0 => /bin/git
Curl: 8.5.0 => /bin/curl
Kernel: Linux 6.6.87.2-microsoft-standard-WSL2 x86_64 GNU/Linux
OS: Ubuntu 24.04.3 LTS (noble)
WSL: 2 (Microsoft Store)
Host glibc: 2.39
Host libstdc++: 6.0.33
/usr/bin/gcc: 13.3.0
/usr/bin/ruby: N/A
glibc: N/A
gcc@12: N/A
gcc: N/A
xorg: N/A

What were you trying to do (and why)?

Keep one formula pinned, while updating another, unrelated formula.

What happened (include all command output)?

brew upgrade & reinstall fail with Error: You must `brew unpin certifi` as installing yq requires the latest version of pinned dependencies. but yq does not depend on certifi.

$ brew outdated
certifi (2025.8.3) < 2025.10.5_1 [pinned at 2025.8.3]
yq (4.47.2) < 4.48.1
yt-dlp (2025.9.26) < 2025.10.14

$ brew deps yq
# nothing

$ brew upgrade yq
==> Upgrading 1 outdated package:
yq 4.47.2 -> 4.48.1
==> Fetching downloads for: yq
Error: You must `brew unpin certifi` as installing yq requires the latest version of pinned dependencies.

$ brew reinstall yq
==> Fetching downloads for: yq
==> Downloading https://ghcr.io/v2/homebrew/core/yq/manifests/4.48.1
Already downloaded: /home/jacktose/.cache/Homebrew/downloads/94fec872cbb560f3e723729b048ef0bde22bc92c1fd768baced8225c51082774--yq-4.48.1.bottle_manifest.json
Error: You must `brew unpin certifi` as installing yq requires the latest version of pinned dependencies.
(Unpinning certifi & installing yq does not upgrade certifi, as expected.)
$ brew unpin certifi

$ brew reinstall yq
==> Fetching downloads for: yq
==> Downloading https://ghcr.io/v2/homebrew/core/yq/manifests/4.48.1
Already downloaded: /home/jacktose/.cache/Homebrew/downloads/94fec872cbb560f3e723729b048ef0bde22bc92c1fd768baced8225c51082774--yq-4.48.1.bottle_manifest.json
==> Fetching yq
==> Downloading https://ghcr.io/v2/homebrew/core/yq/blobs/sha256:e1bf167eb9c36e2652c95b48ffb6f44ea8be0c8bcec9e93c2fbc59f64e87d40c
########################################################################################################################################################################################################## 100.0%
==> Reinstalling yq
==> Pouring yq--4.48.1.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/yq/4.48.1: 10 files, 11.2MB
==> Running `brew cleanup yq`...
Disable this behaviour by setting `HOMEBREW_NO_INSTALL_CLEANUP=1`.
Hide these hints with `HOMEBREW_NO_ENV_HINTS=1` (see `man brew`).
Removing: /home/linuxbrew/.linuxbrew/Cellar/yq/4.47.2.reinstall... (10 files, 11.3MB)
Removing: /home/jacktose/.cache/Homebrew/yq_bottle_manifest--4.47.2... (9.3KB)
Removing: /home/jacktose/.cache/Homebrew/yq--4.47.2... (4.4MB)
==> Caveats
Bash completion has been installed to:
  /home/linuxbrew/.linuxbrew/etc/bash_completion.d
==> Installation times
yq                        0.225 s

$ brew outdated
certifi (2025.8.3) < 2025.10.5_1
yt-dlp (2025.9.26) < 2025.10.14
Of course, the error appears as expected when the pinned formula is a dependency.
$ brew upgrade yt-dlp
==> Upgrading 1 outdated package:
yt-dlp 2025.9.26 -> 2025.10.14
==> Fetching downloads for: yt-dlp
Error: You must `brew unpin certifi` as installing yt-dlp requires the latest version of pinned dependencies.

$ brew deps yt-dlp
berkeley-db@5
bzip2
ca-certificates
certifi  # <-- voila
expat
libedit
libffi
mpdecimal
ncurses
openssl@3
[email protected]
readline
sqlite
unzip
xz
zlib
But I was able to upgrade other, non-dependent formulae with certifi pinned.

(This is from before the above examples were done.)

$ brew upgrade
Warning: Not upgrading 1 pinned package:
certifi 2025.10.5_1
==> Upgrading 7 outdated packages:
oh-my-posh 27.1.0 -> 27.2.0
libxml2 2.13.8 -> 2.13.8_1
[email protected] 3.12.11_1 -> 3.12.12
yq 4.47.2 -> 4.48.1
libunistring 1.4 -> 1.4.1
yt-dlp 2025.9.26 -> 2025.10.14
[email protected] 3.13.7 -> 3.13.8
==> Fetching downloads for: oh-my-posh, libxml2, [email protected], yq, libunistring, yt-dlp and [email protected]
Error: You must `brew unpin certifi` as installing yq requires the latest version of pinned dependencies.
Error: You must `brew unpin certifi` as installing yt-dlp requires the latest version of pinned dependencies.
==> Fetching oh-my-posh
==> Downloading https://ghcr.io/v2/homebrew/core/oh-my-posh/blobs/sha256:10f53a1b134ff156589512a7defbe83f6d9e5db923b1c93a87a185e1061db7ae
########################################################################################################################################################################################################## 100.0%
==> Fetching libxml2
==> Downloading https://ghcr.io/v2/homebrew/core/libxml2/blobs/sha256:36b22e090190179d28083d080e23e6ff112cc690cc34604ea4f606628888368e
########################################################################################################################################################################################################## 100.0%
==> Fetching [email protected]
==> Downloading https://ghcr.io/v2/homebrew/core/python/3.12/blobs/sha256:5b00594526236ecca6e83eef126f31f9c0bf0bdc1233313c44bc1613aba7e09f
########################################################################################################################################################################################################## 100.0%
==> Fetching libunistring
==> Downloading https://ghcr.io/v2/homebrew/core/libunistring/blobs/sha256:f870ec882a5579d1d26fe194454b7c32559268cc0854758b85690385ce844d32
########################################################################################################################################################################################################## 100.0%
==> Fetching [email protected]
==> Downloading https://ghcr.io/v2/homebrew/core/python/3.13/blobs/sha256:0df8c441a5734b0a2388cc3cc761da3f538e48db6710f6637a3515d4814756ef
########################################################################################################################################################################################################## 100.0%
==> Upgrading oh-my-posh
  27.1.0 -> 27.2.0
==> Pouring oh-my-posh--27.2.0.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/oh-my-posh/27.2.0: 131 files, 17.4MB
==> Running `brew cleanup oh-my-posh`...
Disable this behaviour by setting `HOMEBREW_NO_INSTALL_CLEANUP=1`.
Hide these hints with `HOMEBREW_NO_ENV_HINTS=1` (see `man brew`).
Removing: /home/linuxbrew/.linuxbrew/Cellar/oh-my-posh/27.1.0... (131 files, 17.4MB)
Removing: /home/jacktose/.cache/Homebrew/oh-my-posh_bottle_manifest--27.1.0... (6.1KB)
Removing: /home/jacktose/.cache/Homebrew/oh-my-posh--27.1.0... (6.5MB)
==> Upgrading libxml2
  2.13.8 -> 2.13.8_1
==> Pouring libxml2--2.13.8_1.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libxml2/2.13.8_1: 136 files, 7MB
==> Running `brew cleanup libxml2`...
Removing: /home/linuxbrew/.linuxbrew/Cellar/libxml2/2.13.8... (136 files, 7MB)
==> Upgrading [email protected]
  3.12.11_1 -> 3.12.12
==> Pouring [email protected]_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/[email protected]/3.12.12: 3,216 files, 73.3MB
==> Running `brew cleanup [email protected]`...
Removing: /home/linuxbrew/.linuxbrew/Cellar/[email protected]/3.12.11_1... (3,295 files, 75.3MB)
Removing: /home/jacktose/.cache/Homebrew/[email protected]_bottle_manifest--3.12.11_1... (27.5KB)
Removing: /home/jacktose/.cache/Homebrew/[email protected]_1... (19.3MB)
==> Upgrading libunistring
  1.4 -> 1.4.1
==> Pouring libunistring--1.4.1.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/libunistring/1.4.1: 60 files, 6.1MB
==> Running `brew cleanup libunistring`...
Removing: /home/linuxbrew/.linuxbrew/Cellar/libunistring/1.4... (60 files, 6.1MB)
Removing: /home/jacktose/.cache/Homebrew/libunistring_bottle_manifest--1.4... (7.2KB)
Removing: /home/jacktose/.cache/Homebrew/libunistring--1.4... (1.8MB)
==> Upgrading [email protected]
  3.13.7 -> 3.13.8
==> Pouring [email protected]_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/[email protected]/3.13.8: 3,177 files, 71.3MB
==> Running `brew cleanup [email protected]`...
Removing: /home/linuxbrew/.linuxbrew/Cellar/[email protected]/3.13.7... (3,356 files, 75.6MB)
Removing: /home/jacktose/.cache/Homebrew/[email protected]_bottle_manifest--3.13.7... (27KB)
Removing: /home/jacktose/.cache/Homebrew/[email protected]... (19.3MB)
==> Installation times
oh-my-posh                0.307 s
libxml2                   0.290 s
[email protected]               2.820 s
libunistring              0.119 s
[email protected]               2.528 s
I've replicated this with other formulae (bat, openldap) on another system.

This system is too messy to make a good test case, but it makes the point that this is not isolated to the system, install, or formula.

$ brew deps bat
binutils
ca-certificates
gcc
glibc
gmp
isl
libgit2
libmpc
libssh2
[email protected]
lz4
mpfr
oniguruma
# NO openldap
openssl@3
xz
zlib
zstd

$ nice brew reinstall bat -v
==> Fetching downloads for: bat
==> Downloading https://ghcr.io/v2/homebrew/core/bat/manifests/0.25.0_1
Already downloaded: /usr/lusers/jacktose/.cache/Homebrew/downloads/4bcd0ca8c20265515b2d1f36c88699d6fab1d5f03428b782aa1295f6c15c5c80--bat-0.25.0_1.bottle_manifest.json
Error: You must `brew unpin openldap` as installing bat requires the latest version of pinned dependencies.

$ brew unpin openldap

$ nice brew reinstall bat -v
==> Fetching downloads for: bat
==> Downloading https://ghcr.io/v2/homebrew/core/bat/manifests/0.25.0_1
Already downloaded: /usr/lusers/jacktose/.cache/Homebrew/downloads/4bcd0ca8c20265515b2d1f36c88699d6fab1d5f03428b782aa1295f6c15c5c80--bat-0.25.0_1.bottle_manifest.json
==> Fetching bat
==> Downloading https://ghcr.io/v2/homebrew/core/bat/blobs/sha256:68f6c503b8895e4390935142c771030aca2d70b7fb3fc72449df664e05af1680
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 2658k  100 2658k    0     0  5991k      0 --:--:-- --:--:-- --:--:-- 5991k
==> Verifying checksum for 'c7722f55516492df6281fb3ec598580a4d0623bb5c1a11b55fee86817e4b0fa2--bat--0.25.0_1.x86_64_linux.bottle.tar.gz'
==> Reinstalling bat
==> Pouring bat--0.25.0_1.x86_64_linux.bottle.tar.gz
mv /var/tmp/homebrew-unpack-20251015-1666-p6e18j/bat/0.25.0_1 /data/shared/lusers/jacktose/homebrew/Cellar/bat/0.25.0_1
==> Finishing up
ln -s ../../Cellar/bat/0.25.0_1/etc/bash_completion.d/bat bat
ln -s ../Cellar/bat/0.25.0_1/bin/bat bat
ln -s ../../../Cellar/bat/0.25.0_1/share/fish/vendor_completions.d/bat.fish bat.fish
ln -s ../../../Cellar/bat/0.25.0_1/share/man/man1/bat.1 bat.1
ln -s ../../../Cellar/bat/0.25.0_1/share/zsh/site-functions/_bat _bat
==> Summary
🍺  /data/shared/lusers/jacktose/homebrew/Cellar/bat/0.25.0_1: 15 files, 5MB
==> Running `brew cleanup bat`...
Disable this behaviour by setting `HOMEBREW_NO_INSTALL_CLEANUP=1`.
Hide these hints with `HOMEBREW_NO_ENV_HINTS=1` (see `man brew`).
==> Caveats
Bash completion has been installed to:
  /data/shared/lusers/jacktose/homebrew/etc/bash_completion.d
==> Installation times
bat                       2.254 s

What did you expect to happen?

Any formula that does not depend on a pinned formula should install/reinstall/upgrade without error.

Step-by-step reproduction instructions (by running brew commands)

brew install yt-dlp  # includes certifi dependency
brew install yp
brew pin certifi
brew reinstall yp
# OR wait for them to become outdated, then
brew upgrade yp

(I haven't tried this with a fresh install, so it may relate to some subtler state.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions