troubleshootingerrorsdebugging

Gemini CLI Not Working? Evidence-Based Fixes for Every Error Category

Systematic analysis of Gemini CLI failure modes — authentication 401/403, rate limits 429, hangs, PATH conflicts, and configuration drift — with real GitHub issue citations and diagnostic commands.

muzhihao
16 min read

Introduction

After scanning the open issue tracker at github.com/google-gemini/gemini-cli — which at the time of writing holds tens of thousands of filed reports — five failure categories account for the overwhelming majority of "Gemini CLI not working" complaints: installation and PATH errors, authentication failures (401 / 403), rate limit exhaustion (429), process hangs, and silent configuration drift. These categories are not equally distributed. Across the issues reviewed, authentication and rate-limit problems together represent the densest cluster, while hang reports subdivide cleanly into two distinct root causes that share no fix.

The official Gemini CLI troubleshooting guide documents exit codes 41–53, certificate errors, and CI-environment detection quirks, but stops well short of the community-discovered failure modes that dominate recent issue threads. This article synthesises both sources.

What follows is an analyst synthesis, not a hands-on walkthrough. Every claim is linked to a primary source — a numbered GitHub issue, an official doc page, or a Google support thread. The goal is to let you match your specific error output to a documented root cause before spending time on fixes that do not apply.


TL;DR

  • Installation / PATH failures on Linux trace primarily to a legacy-path conflict introduced when Gemini CLI's install location changed between versions — issue #5886 documents the exact which gemini test that reveals it.
  • 403 Forbidden errors split into two unrelated causes: API-not-enabled (fixable in Cloud Console) and an account-tier routing bug affecting Google One AI Pro subscribers — issue #24517 has 141 comments and remains open at priority/p1.
  • 429 RESOURCE_EXHAUSTED on paid accounts is frequently caused by AI Studio being silently downgraded to "Free Tier" after Google's January 2026 billing restructure, not by actual overuse — issue #24396 explains the manual billing-link workaround.
  • Hangs on "Initializing..." in Linux / proxy environments are caused by a missing ripgrep binary that triggers a silent 300-second network timeout — issue #20433 has the one-line symlink fix.
  • Configuration drift happens because environment variables (GEMINI_MODEL, GEMINI_API_KEY) silently override settings.json; the official troubleshooting doc confirms this precedence order.

Problem Domain in Detail

The Gemini CLI is a Node.js process that calls a remote API — Google's Generative Language API — over HTTPS. The failure surface therefore spans four distinct layers: your local install, your shell environment, your network path, and Google's backend. Errors at each layer produce different output signatures, and the most common diagnostic mistake is applying a fix from the wrong layer.

Layer 1 — Local install. The binary is either missing, on the wrong PATH, or pointed at a stale version. Signature: command not found or unexpected JavaScript stack traces on startup. Issue #2264 illustrates the npm install failure pattern on mismatched Node versions.

Layer 2 — Shell environment. API keys, model overrides, or proxy settings are wrong, missing, or conflict with config files. Signature: 401 / 403 responses, or the CLI behaves differently depending on which terminal you open.

Layer 3 — Network. Corporate firewalls, proxy servers, or missing system dependencies (specifically ripgrep — see issue #20433) block connections silently or cause multi-minute hangs.

Layer 4 — Google backend. Rate limits, quota exhaustion, account-tier mismatches, or transient service outages. Signature: 429, 403 PERMISSION_DENIED with zero tokens consumed, or 500/503 responses.

# One-minute triage: determine which layer is failing
gemini --version                          # Layer 1: binary present?
echo "Key: ${GEMINI_API_KEY:0:8}..."      # Layer 2: key set?
curl -s --max-time 5 https://generativelanguage.googleapis.com -o /dev/null -w "%{http_code}"
                                          # Layer 3: network reachable? (expect 404, not ETIMEDOUT)
curl -s "https://generativelanguage.googleapis.com/v1beta/models?key=$GEMINI_API_KEY" | head -c 100
                                          # Layer 4: key accepted by backend?

Common Approaches and Why They Fail

"Just reinstall the CLI" resolves corrupted installs but fails for the most common causes — authentication errors and rate limits — because the problem is not in the binary. Issue #5886 specifically documents cases where reinstall via npm install -g appears to succeed yet the shell continues executing the old binary from /usr/local/bin, because the new install writes to /usr/bin and standard $PATH puts /usr/local/bin first.

"Regenerate your API key" is frequently recommended but fails for 403 PERMISSION_DENIED errors that stem from the API not being enabled for the project, or from the account-tier routing bug in issue #24517. A new key from the same disabled project produces the same 403.

"Wait and retry for 429" is correct for transient rate limiting but wrong for the quota-zeroed state documented in issue #24396, where the error message reads "limit: 0" — no amount of waiting resolves a limit of zero; the billing link must be established first.


Evidence-Based Fixes by Error Category

Category 1: Installation and PATH Errors

Of the installation failures indexed on GitHub, three sub-causes recur: PATH conflict from legacy install location, npm permission errors on Linux, and Node.js version mismatch.

PATH conflict (Linux — upgraded from older version).
Issue #5886 documents a structural change in Gemini CLI's install location: older versions wrote to /usr/local/bin/gemini, newer versions write to /usr/bin/gemini. Standard Linux $PATH searches /usr/local/bin before /usr/bin, so after a normal npm install -g update, which gemini still returns the old path and the shell executes the stale binary.

# Diagnose: does which gemini point to the new location?
which gemini
# If output is /usr/local/bin/gemini, you have the legacy conflict.

# Fix: manually remove the zombie executable, then reinstall
sudo rm /usr/local/bin/gemini
sudo rm -rf /usr/local/lib/node_modules/@google/gemini-cli
npm install -g @google/gemini-cli
which gemini    # should now return /usr/bin/gemini or your nvm path

npm permission errors (Linux / Debian-family).
Never run sudo npm install -g. Instead, configure npm's global prefix to a user-owned directory, or use nvm which installs per-user by default:

# Option A: configure npm prefix to ~/.local
npm config set prefix ~/.local
export PATH="$HOME/.local/bin:$PATH"   # add to ~/.bashrc or ~/.zshrc
npm install -g @google/gemini-cli

# Option B: use nvm
nvm install --lts && nvm use --lts
npm install -g @google/gemini-cli

Node.js version mismatch. The official npm package page for @google/gemini-cli requires Node.js 20+. Ubuntu 22.04/24.04 ships Node 18 from its default repositories. Running on Node 18 produces inconsistent startup failures rather than a clean error message — issue #2264 illustrates this pattern.

node --version    # must be v20.0.0 or higher
# If not, install via nvm: nvm install 20 && nvm use 20

Category 2: Authentication Errors (401 / 403)

401 UNAUTHENTICATED — key missing or malformed.
The GEMINI_API_KEY environment variable is not exported to the current shell session. Keys can also silently acquire trailing whitespace or a newline character during copy-paste, causing the API to reject them as malformed even though echo $GEMINI_API_KEY looks correct.

# Check actual byte length vs. expected (~39 chars for AIza... keys)
echo -n "$GEMINI_API_KEY" | wc -c

# Re-set cleanly to strip any trailing whitespace
export GEMINI_API_KEY=$(printf '%s' 'AIzaYourKeyHere')

# Persist to shell profile
echo 'export GEMINI_API_KEY="AIzaYourKeyHere"' >> ~/.zshrc
source ~/.zshrc

Newly created API keys can take up to five minutes to propagate through Google's systems. An "invalid API key" error immediately after generating a new key in AI Studio may self-resolve without any action.

403 PERMISSION_DENIED — API not enabled for project.
The API key belongs to a Google Cloud project where the Generative Language API has not been explicitly enabled. Navigate to console.cloud.google.com → APIs & Services → Library, search "Generative Language API", and confirm it shows "Enabled". A 403 from a key in this state looks identical to the account-tier bug below — the distinguishing test is whether the curl direct call also 403s.

# If this curl also returns {"error":{"code":403,...}}, the problem is the project/API, not the CLI
curl -s "https://generativelanguage.googleapis.com/v1beta/models?key=$GEMINI_API_KEY" | python3 -m json.tool | head -10

403 PERMISSION_DENIED — account-tier routing bug (Google One AI Pro).
Issue #24517 (priority/p1, 141 comments, open as of April 2026) documents a distinct 403 where OAuth authentication succeeds, the CLI correctly identifies the subscription tier as "Gemini Code Assist in Google One AI Pro", and /stats shows 0 input tokens with 0 output tokens — requests are rejected before any processing occurs. The error has escalated from 429 RESOURCE_EXHAUSTED for some users.

The distinguishing signature is: /stats Auth Method shows "Signed in with Google" (OAuth, not API key), subscription tier is identified correctly, yet every request fails. As of the issue's last update, the Google-side fix is pending. The current workaround is to switch from OAuth to an API key with an attached billing account.


Category 3: Rate Limit Errors (429 RESOURCE_EXHAUSTED)

Of the 429 issues reviewed, two root causes are structurally different and require different responses:

Transient rate limiting — genuinely exceeding requests-per-minute (RPM) or tokens-per-minute (TPM). Issue #2305 and issue #10722 document the standard pattern: free-tier users hitting rate limits after a few moderately sized prompts. The fix is exponential backoff and, where possible, switching to gemini-2.5-flash which carries higher free-tier quotas than gemini-2.5-pro.

# The CLI's own fallback: switch to flash for the current session
# Or set it permanently in .gemini/settings.json:
{
  "model": "gemini-2.5-flash"
}

# Check quota usage in the Cloud Console:
# https://console.cloud.google.com/apis/api/generativelanguage.googleapis.com/quotas

False 429 with limit: 0 (billing restructure, January 2026). Issue #24396 identifies a distinct failure mode: after Google's January 2026 restructuring of AI benefits, some Google One AI Pro subscribers found their AI Studio project silently downgraded to Free Tier. The 429 error includes "limit": 0, meaning no amount of waiting or backoff resolves it.

The documented workaround from issue #24396: navigate to aistudio.google.com → Settings → Billing, manually link a billing account, and claim the "Google Developer Program Premium" perk under your Google One benefits. This bridges the gap between the subscription and the API Studio project tier.

# Diagnostic: if you see "limit": 0 in the error JSON, it is the billing issue
gemini --debug "hello" 2>&1 | grep -A 5 '"limit"'
# "limit": 0 → billing fix required
# "limit": <positive number> → genuine rate limit, use backoff

Category 4: Process Hangs

Hang reports on the issue tracker break into two unrelated root causes.

"Initializing..." hang (3–5 minutes) on Linux / proxy environments.
Issue #20433 (28 comments, closed with workaround) identifies the root cause: the CLI internally depends on ripgrep (rg). On startup it looks for rg at ~/.gemini/tmp/bin/rg. If missing, it silently attempts to download the binary in the background. In proxy-restricted or air-gapped Linux environments, this download fails silently and hits a 300-second timeout, dead-locking the TUI.

# Diagnose: does rg exist?
which rg || echo "ripgrep not found"
ls ~/.gemini/tmp/bin/rg 2>/dev/null || echo "CLI-local rg not found"

# Fix: install ripgrep and symlink it to the CLI's expected path
sudo apt-get install ripgrep          # Debian/Ubuntu
# or: brew install ripgrep            # macOS
mkdir -p ~/.gemini/tmp/bin
ln -sf $(which rg) ~/.gemini/tmp/bin/rg

The referenced Japanese technical analysis (linked in issue #20433) measured the exact 300-second hang duration, confirming it matches a standard network timeout, not an application-level hang.

"Thinking" hang with high request count / low output tokens.
Issue #22415 (28 comments, open) documents a different pattern: the CLI shows "This is taking a bit longer, we're still on it" indefinitely, and after force-termination /stats reveals a large number of API requests (e.g. 22 Reqs) with nearly zero output tokens. The root cause is a retry loop in the agent: the preview model returns output in a format the agent cannot parse, triggering silent background retries.

# Reproduce diagnostic: run with a simple prompt and watch /stats
# Force-terminate with Ctrl+C if it hangs, then type /stats

# Mitigation: avoid preview model designations for production use
# Switch to a stable model in .gemini/settings.json:
{
  "model": "gemini-2.5-pro"   # not gemini-3.1-pro-preview
}

Issue #20525 documents a related timeout pattern for users behind software firewalls: the CLI requires explicit network permission on first run. On Windows, a firewall prompt appears; accepting it is required before any connections will complete.


Category 5: Configuration Drift

Configuration drift occurs when the active behaviour diverges from what settings.json specifies, with no error message to explain why.

Environment variable precedence. The official Gemini CLI troubleshooting guide confirms that environment variables take precedence over settings.json. GEMINI_MODEL overrides the model field, GEMINI_API_KEY overrides any auth configuration. To test your settings file in isolation:

# Print all active Gemini env vars
env | grep -i gemini

# Run with env vars stripped to test settings.json alone
env -u GEMINI_MODEL -u GEMINI_API_KEY gemini --debug "test"

CI environment false-positive. The official troubleshooting guide documents that the CLI uses the is-in-ci package to detect non-interactive environments. Any environment variable prefixed with CI_ (e.g. CI_TOKEN) triggers non-interactive mode — no prompt appears. The fix:

env -u CI_TOKEN gemini    # unset the offending CI_ variable for this session

DEBUG=true placement. The official guide specifically notes that a DEBUG=true entry in a project .env file at the root is not read; it must be placed in .gemini/.env instead.

GEMINI.md not loading. If the project context file has no effect, confirm the file is named exactly GEMINI.md (case-sensitive), is located at the project root, and that contextFileName in settings.json has not been customised to a different value.

ls -la GEMINI.md    # must exist at project root
python3 -c "import sys,json; d=json.load(open('.gemini/settings.json')); print(d.get('contextFileName','GEMINI.md (default)'))"

Quantified Analysis

From the GitHub issues reviewed for this article:

| Category | Indicator | Status | |---|---|---| | Rate limit (429) | Highest open-issue volume; #24396 accumulated 22 comments within weeks | Partially billing-related since Jan 2026 | | Auth 403 | #24517 reached 141 comments, priority/p1 — escalated from 429 for some users | Open; Google-side fix pending | | Hang / init | #20433 closed with symlink workaround, not a code fix | Root cause (missing ripgrep) unfixed in CLI | | PATH conflict | #5886 marked Stale / priority/p3 | Reproducible but low priority for maintainers | | Config drift | Fewer standalone issues; often misattributed to auth or rate limits | No dedicated tracking |

The official guide's exit-code table (41–53) provides a machine-readable failure taxonomy useful for CI diagnostic scripts.


Edge Cases Documented in Community Reports

TLS certificate error in corporate environments. The official guide documents UNABLE_TO_GET_ISSUER_CERT_LOCALLY as a known error on corporate networks with SSL inspection. The prescribed fix is setting NODE_EXTRA_CA_CERTS to the absolute path of the corporate root CA certificate. Setting NODE_TLS_REJECT_UNAUTHORIZED=0 disables all certificate verification and is explicitly not recommended by the official guide except as a temporary local diagnostic.

EADDRINUSE on MCP server startup. The official troubleshooting guide documents this error: another process holds the port the MCP server is configured to bind. The fix is to stop the conflicting process (lsof -i :<port> on macOS/Linux) or configure the MCP server to use a different port.

403 Forbidden on /v1internal:loadCodeAssist. Issue #10110 documents a case where the OAuth "Login with Google" flow completes successfully but the CLI then fails with 403: Your client does not have permission to get URL /v1internal:loadCodeAssist. This error indicates the CLI attempted to authenticate against the enterprise Gemini Code Assist endpoint instead of the consumer endpoint, a routing issue tied to how the CLI interprets subscription tier. The workaround is to use API key authentication instead of OAuth.

gemini debug --all > debug.txt. The official guide recommends attaching this command's output to any bug report. The team explicitly triages reports faster when this file is attached. For issues that are hard to reproduce, running this command in the broken session is the single highest-value diagnostic step.

Windows PowerShell execution policy blocks. On Windows, npm global installs succeed but the gemini command fails with a script execution policy error. The resolution is to run Set-ExecutionPolicy RemoteSigned -Scope CurrentUser in PowerShell before invoking the CLI — this is standard Node.js global install behaviour on Windows and is not specific to Gemini CLI. Issue #2170 documents the symptom pattern on Windows.


Recommendation

Based on the five failure patterns documented above, the most reliable troubleshooting sequence is:

  1. Determine the layer first. Run the four-command triage block in the Problem Domain section. Skipping this step is the most common source of wasted effort — every category looks similar until you isolate which layer is failing.
  2. For 403: run a direct curl with your API key. If curl also returns 403, the problem is your Google Cloud project (API not enabled). If curl succeeds but the CLI fails under OAuth, you are likely hitting the backend routing bug in issue #24517.
  3. For 429: check whether "limit": 0 appears in the error JSON with gemini --debug. If it does, backoff will not help — follow the billing-link fix in issue #24396.
  4. For Linux hangs at startup: run which rg before anything else. The symlink fix from issue #20433 takes thirty seconds and eliminates the 300-second hang entirely.
  5. For config surprises: run env | grep -i gemini before editing settings.json. One environment variable silently overrides the entire file.

FAQ

Q: Why does the CLI work in one terminal but fail in another?

Environment variable inheritance. GEMINI_API_KEY set with export in one shell session is not available in a new terminal window unless it is persisted in your shell profile (.zshrc, .bashrc). This is the documented explanation in the official troubleshooting guide and is the most common "worked yesterday, broken today" pattern seen in issue reports.

Q: The CLI shows my subscription tier correctly but every request fails with 403. How is that possible?

Issue #24517 documents exactly this: OAuth authentication succeeds, the subscription is identified, and /stats reports the correct tier — but API calls return 403 PERMISSION_DENIED with zero tokens consumed. This is a backend routing bug affecting Google One AI Pro subscribers, not a local configuration problem. The issue is open at priority/p1 as of April 2026.

Q: I'm getting 429 errors but I have a paid subscription and haven't sent many requests.

Check whether "limit": 0 appears in the error body. Issue #24396 documents that after Google's January 2026 AI benefit restructuring, many paid subscribers' AI Studio projects were silently placed on the Free Tier, resulting in a hard limit of zero for newer models. The fix involves manually linking a billing account and claiming the Developer Program Premium perk in AI Studio settings.

Q: The CLI hangs for several minutes every time I start it on Linux.

Install ripgrep and create a symlink as documented in issue #20433: sudo apt-get install ripgrep && mkdir -p ~/.gemini/tmp/bin && ln -sf $(which rg) ~/.gemini/tmp/bin/rg. This eliminates the 300-second startup hang caused by the CLI's failed background attempt to download the binary in proxy-restricted environments.

Q: How do I write a bug report that actually gets fixed?

The official guide's recommendation: run gemini debug --all > debug.txt in the broken session and attach the output to your GitHub issue. Reports with this file attached are triaged faster. Also include the output of gemini --version, node --version, and your OS, along with the minimal prompt that reproduces the issue.

Was this article helpful?