# Claude Code Not Updating? 12 Causes and Fixes

> **30-second test:** in your shell (not inside a session), run `claude --version`, then `claude update`, then `claude --version` again. If `claude update` prints `Successfully updated from <old> to version <new>` but sessions still show the old version, start at cause 1. If it prints `Claude is up to date!`, you're on Homebrew, WinGet or apk: go to cause 2. If it prints an error, find it in the table below.

Native installs of Claude Code update themselves: Claude Code checks for updates on startup and periodically while running, downloads and installs the new version in the background, and the update takes effect the next time you start it. Homebrew, WinGet, apt, dnf and apk installs don't auto-update by default. So "it never updates" usually means a missing restart, an install method that doesn't self-update, or a setting that switched updates off.

## Two commands that tell you most of it

- **`claude doctor`** prints read-only installation and settings diagnostics without starting a session. Look at the `Auto-updates` line (it shows `enabled`, or `disabled (set by env: DISABLE_AUTOUPDATER)` when that's set) and the `Last update attempt` line, which records the result of the last background update.
- **`claude update`** applies an update right away. It reports `Successfully updated from <old> to version <new>`, or `Claude Code is up to date (<version>)` if you already have the newest one. Installs managed by Homebrew, WinGet or apk report `Claude is up to date!` instead.

## Match your error

| You see | Go to |
|---|---|
| `Auto-update failed · Run claude doctor` in red in the session footer | The section right below |
| `Claude is up to date!` but you're behind | Causes 2 and 3 |
| `Auto-updates: disabled (set by env: ...)` in `claude doctor` | Cause 5 |
| A one-time notice that the npm global install can't auto-update, or `EACCES` | Cause 7 |
| `npm error code ENOTEMPTY` | Cause 7 |
| `The connection dropped while downloading the update` or `Download timed out: exceeded the total deadline` | Cause 9 |
| `Release verification failed for Claude Code <version> (<reason>). The update was not installed.` | Cause 10 |
| `claude update` hangs after `Checking for updates` | Cause 11 |
| `'claude' is not recognized` right after an update on Windows | Cause 12 |

## `Auto-update failed · Run claude doctor` in the footer

This red line means Claude Code tried to update itself in the background and the update didn't install. You can keep working; nothing is broken. `claude doctor` will only show `Last update attempt: failed (install_failed)` with a date and no cause, so skip it: run `claude update` in your shell instead. That either finishes the update or prints the real error, which you can match in the table above.

## 12 causes, in the order to check them

1. **The update installed, but you haven't restarted.** Background updates take effect the next time you start Claude Code, so a session that's been open for days keeps running the old version. Exit the session and start `claude` again, then check `claude --version`.
2. **Your install method doesn't auto-update.** Only native installs (the `curl ... install.sh`, `install.ps1` or `install.cmd` installer) update in the background. Upgrade the others yourself: `brew upgrade claude-code` (or `brew upgrade claude-code@latest`), `winget upgrade Anthropic.ClaudeCode`, `sudo apt update && sudo apt upgrade claude-code`, `sudo dnf upgrade claude-code`, or `apk update && apk upgrade claude-code`. For Homebrew and WinGet you can opt in to automatic upgrades by setting `CLAUDE_CODE_PACKAGE_MANAGER_AUTO_UPDATE=1`: Claude Code then runs the upgrade in the background when a new version is available and shows a restart prompt on success. On WinGet that upgrade can fail while Claude Code is running because Windows locks the executable, and Claude Code shows you the manual command instead. apt, dnf and apk always need a manual upgrade because they need elevated privileges. Known issue: Claude Code can tell you about an update before the package manager has it, so if an upgrade fails, wait and try later.
3. **You're on the stable channel, on purpose or not.** Native installs follow the `latest` channel by default. The `stable` channel serves a version that's typically about a week old and skips releases with major regressions, so being "behind" is expected there. Check `/config` → **Auto-update channel**, or look for `"autoUpdatesChannel": "stable"` in your settings files; `claude install stable` also saves that choice. On Homebrew the cask name decides instead: `claude-code` tracks stable and `claude-code@latest` tracks latest, and the `autoUpdatesChannel` setting is ignored. If `brew upgrade --cask claude-code@latest` says `Cask 'claude-code@latest' is not installed`, run `brew list --cask | grep claude-code` and upgrade the cask it prints. An older version than expected right after `brew install` usually means a stale cask index: run `brew update` first. A newly launched model can need a version newer than stable serves; switch to latest to use it right away.
4. **A `minimumVersion` or managed version range is in play.** `minimumVersion` is a floor: background updates and `claude update` refuse to install anything below it. Claude Code writes it for you when you switch from latest to stable in `/config` and choose to stay on your current version, and clears it when you switch back to latest. In an organization, the managed settings `requiredMinimumVersion` and `requiredMaximumVersion` make Claude Code refuse to start outside a version range, and updates skip versions above the ceiling. If your company set a ceiling, staying below it is the intended behavior; ask your admin.
5. **Something switched updates off.** Check your shell profile and the `env` block of every settings file (user, project, local and managed) for three variables. `DISABLE_AUTOUPDATER=1` stops background updates only; `claude update` and `claude install` still work. `DISABLE_UPDATES=1` blocks every update path, including manual `claude update` and `claude install`; teams that ship Claude Code through their own channel set it. `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` disables nonessential network traffic, and auto-updates are part of that; setting it to `0` or `false` still disables it, so unset the variable instead. On a native or npm install, `claude doctor` shows which variable turned auto-updates off. Not sure which settings file is setting it? Our free [settings precedence checker](https://solostackkits.netlify.app/tools/settings-precedence-checker.html) shows which file wins, and [settings not applying](https://solostackkits.netlify.app/blog/claude-code-settings-not-applying.html) explains where each key belongs.
6. **Two installs, and the updated one isn't the one you run.** An npm global install, a legacy `~/.claude/local/` install, Homebrew and the native installer can all sit on your PATH at once. Updating one leaves `claude` pointing at another. Run `which -a claude` (Windows: `where.exe claude`), plus `ls -la ~/.local/bin/claude`, `ls -la ~/.claude/local/` and `npm -g ls @anthropic-ai/claude-code`. Keep one, ideally the native install, and remove the rest (`npm uninstall -g @anthropic-ai/claude-code`, `rm -rf ~/.claude/local`). Our [Claude Code command not found](https://solostackkits.netlify.app/blog/claude-code-command-not-found.html) guide walks through the cleanup for each method.
7. **npm can't write its global folder.** If the npm global directory isn't writable, an npm install can't auto-update: Claude Code shows a one-time notice at startup and `claude doctor` lists the available fixes. Don't use `sudo npm install -g`; Anthropic warns it causes permission issues and security risks. The documented fix for npm permission errors is to switch to the native installer (`curl -fsSL https://claude.ai/install.sh | bash`) and then remove the npm copy (cause 6). If you stay on npm, upgrade with `npm install -g @anthropic-ai/claude-code@latest`, not `npm update -g`, which respects the original semver range and may not move you to the newest release. `npm error code ENOTEMPTY` during an update means a leftover folder: delete the directory named on the `npm error path` line and any `.claude-code-*` folders next to it (`rm -rf "$(npm root -g)/@anthropic-ai/claude-code"` and `rm -rf "$(npm root -g)/@anthropic-ai/.claude-code-"*`), then reinstall.
8. **You replaced the native launcher.** On macOS and Linux the native installer manages `~/.local/bin/claude` as a symlink into `~/.local/share/claude/versions/`. If you swapped it for your own script or symlink, updates still install new versions under `versions/`, but your launcher decides which one runs, and Claude Code keeps every installed version on disk. `claude doctor` reports a launcher the installer didn't create. To hand control back, remove `~/.local/bin/claude` and run `claude update`. If native-install folders aren't writable (`~/.local/bin`, `~/.local/share/claude`, `~/.claude`), check with `test -w ~/.local/bin && echo writable`, and fix ownership with `sudo mkdir -p ~/.local/bin` and `sudo chown -R $(whoami) ~/.local`.
9. **The download dropped or timed out.** `The connection dropped while downloading the update (attempt 3/3: ...)` means the connection to the download server closed and three attempts didn't recover; `Download timed out: exceeded the total deadline` means the download didn't finish within 10 minutes. Run `claude update` again, ideally on a faster network. Test the host with `curl -sI https://downloads.claude.ai/claude-code-releases/latest` (Windows: `curl.exe -sI ...`): `200` means reachable, `403` usually means a proxy or filter, and no output means your network blocks it. Behind a corporate proxy, set `HTTPS_PROXY` (and `HTTP_PROXY`) before running `claude update`, and ask your network team to allow the full download from `downloads.claude.ai`; proxies sometimes cut off large downloads. Our [proxy and SSL certificate errors guide](https://solostackkits.netlify.app/blog/claude-code-proxy-ssl-certificate-error.html) covers the rest of the proxy setup.
10. **`Release verification failed`.** Claude Code couldn't confirm the release was genuine, so it installed nothing and your current version keeps working. If the reason in parentheses starts with `sidecar_fetch_`, run the same command again from your shell. For any other reason, try again later. If it keeps happening, report it with the full message.
11. **`claude update` hangs after `Checking for updates`.** Before v2.1.214, `claude update` and `claude doctor` hung when one of your shell config paths (`~/.zshrc`, `~/.bashrc`, `~/.config/fish/config.fish`, or on macOS `~/.bash_profile`, `~/.bash_login`, `~/.profile`) was a directory instead of a file. Find it with `ls -ld ~/.zshrc ~/.bashrc ~/.bash_profile ~/.bash_login ~/.profile ~/.config/fish/config.fish` (a line starting with `d` is the culprit) and move it aside. Since `claude update` itself hangs on those versions, update by rerunning the install script instead.
12. **Windows and WSL quirks.** On Windows, Claude Code updates by renaming `claude.exe` to a backup and moving the new one in. If that fails, `%USERPROFILE%\.local\bin` can be left with only `claude.exe.old.<timestamp>`. Restore it in PowerShell with `Get-ChildItem "$env:USERPROFILE\.local\bin\claude.exe.old.*" | Sort-Object Name | Select-Object -Last 1 | Rename-Item -NewName claude.exe`, or rerun `irm https://claude.ai/install.ps1 | iex` if there's no backup. In WSL, install, run and update Claude Code inside the WSL terminal, not from PowerShell or CMD. If you used npm inside WSL and it reports a platform mismatch, WSL is picking up the Windows `npm`: run `npm config set os linux`, then `npm install -g @anthropic-ai/claude-code --force` (no `sudo`). `which npm` and `which node` paths starting with `/mnt/c/` mean you're using Windows Node; install Node inside Linux with your package manager or nvm. More Windows-specific fixes are in [Claude Code not working on Windows](https://solostackkits.netlify.app/blog/claude-code-windows-not-working.html).

## Staying on a version on purpose

Sometimes you want the opposite: hold a version that works while a new release settles.

- **Follow stable instead of latest:** `/config` → **Auto-update channel**, or `"autoUpdatesChannel": "stable"` in settings.json.
- **Install an exact version:** `claude install 2.1.89` (or `curl -fsSL https://claude.ai/install.sh | bash -s 2.1.89`; PowerShell: `& ([scriptblock]::Create((irm https://claude.ai/install.ps1))) 2.1.89`). `claude --version` should then print `2.1.89 (Claude Code)`.
- **Then keep it there:** add `"env": { "DISABLE_AUTOUPDATER": "1" }` to settings.json so background updates don't move you forward. Remember to remove it later, or you'll be back at cause 5.

## Still stuck?

If `claude` isn't found at all after an update or reinstall, see [Claude Code command not found](https://solostackkits.netlify.app/blog/claude-code-command-not-found.html). If the update worked but you now get errors on every turn, [Claude Code API errors](https://solostackkits.netlify.app/blog/claude-code-api-error.html) and [Claude Code stuck or not responding](https://solostackkits.netlify.app/blog/claude-code-stuck-or-not-responding.html) cover the usual causes. Prefer to build a config yourself? Use the [free Claude Code tools](https://solostackkits.netlify.app/tools/) — they run in your browser, no signup.

---

Facts on this page come from Anthropic's Claude Code docs on [advanced setup and updates](https://code.claude.com/docs/en/setup), [troubleshooting installation and login](https://code.claude.com/docs/en/troubleshoot-install), the [CLI reference](https://code.claude.com/docs/en/cli-reference), [environment variables](https://code.claude.com/docs/en/env-vars) and the [settings reference](https://code.claude.com/docs/en/settings-reference). This guide isn't affiliated with Anthropic.

Want a tested starting point? Our [Claude Code Power Config Pack](https://solostackkits.gumroad.com/l/claude-code-config-pack/LAUNCH50?utm_source=hashnode&utm_medium=article&utm_campaign=ssk_hashnode_update) has 6 lean CLAUDE.md templates, permission presets and 8 tested safety hooks, $6 with the launch code while it lasts.

Not ready to buy? Our [free safety hooks](https://solostackkits.gumroad.com/l/claude-code-free-safety-hooks?utm_source=hashnode&utm_medium=article&utm_campaign=ssk_hashnode_update) block risky commands before they run.
