SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-09-15

Sửa lỗi Claude Code báo API key không hợp lệ

Claude Code báo “invalid API key” dù bạn có subscription? Tìm ANTHROPIC_API_KEY còn sót trên VPS và hiểu vì sao /login không sửa được lỗi này.

Vì sao Claude Code báo lỗi API key không hợp lệ

Claude Code báo lỗi Invalid API key vì hai nguyên nhân khác nhau, và cách xử lý hai trường hợp này hoàn toàn ngược nhau. Có thể bạn định xác thực bằng API key nhưng key đó sai, đã bị thu hồi hoặc thuộc tài khoản khác. Cũng có thể bạn không hề định dùng key, nhưng một ANTHROPIC_API_KEY còn sót lại trong environment của server đang được ưu tiên hơn subscription mà bạn đã đăng nhập. Theo tài liệu của Anthropic tại thời điểm tháng 9 năm 2026, trường hợp thứ hai được nêu rất rõ: key được đặt trong environment sẽ được dùng thay cho subscription Claude Pro, Max, Team hoặc Enterprise, ngay cả khi bạn đã đăng nhập.

Hãy xác định mình đang ở trường hợp nào trước khi thay đổi bất cứ thứ gì. Khởi động Claude Code rồi chạy /status. Tài liệu mô tả một dòng Login method hiển thị tài khoản subscription của bạn và một dòng API key xuất hiện khi đang dùng API key. Nếu bạn thấy dòng API key trên một máy mà trước đó bạn chỉ chạy /login, thì vấn đề nằm trong environment; xác thực lại sẽ không thay đổi biến này.

Mọi lệnh bên dưới đều được chạy trên server của bạn. Hãy đọc output trước khi thực hiện bước tiếp theo.

Thứ tự credential và lý do /login không giúp được

Khi có nhiều credential, Claude Code chọn theo thứ tự đã được tài liệu hóa:

  • Credential của cloud provider, khi đã đặt CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX hoặc CLAUDE_CODE_USE_FOUNDRY.
  • Biến ANTHROPIC_AUTH_TOKEN, được gửi dưới dạng header Authorization: Bearer.
  • Biến ANTHROPIC_API_KEY, được gửi dưới dạng header X-Api-Key.
  • Kết quả của một script apiKeyHelper.
  • Biến CLAUDE_CODE_OAUTH_TOKEN, chứa token từ claude setup-token.
  • Credential của profile Anthropic và federation.
  • Credential OAuth của subscription do /login ghi vào.

Hãy đọc danh sách này từ dưới lên. /login ghi credential ở vị trí cuối cùng. Trên Linux, credential này được lưu trong ~/.claude/.credentials.json với file mode 0600. Mọi credential trong environment ở phía trên đều được ưu tiên hơn. Vì vậy, một lần đăng nhập mới chỉ refresh credential mà session không bao giờ dùng đến: lệnh login đã chạy thành công, nhưng credential đó vẫn bị bỏ qua. Đây là toàn bộ lý do cách sửa hiển nhiên không có tác dụng.

Interactive session có thêm một bước khiến nhiều người nhầm lẫn. Tài liệu cho biết bạn sẽ được hỏi một lần để chấp nhận hoặc từ chối API key tìm thấy trong environment, và lựa chọn này sẽ được ghi nhớ. Lựa chọn bạn đã xác nhận từ vài tháng trước vẫn còn hiệu lực. Bạn thay đổi lựa chọn này bằng toggle "Use custom API key" trong /config. Toggle đó chỉ xuất hiện khi ANTHROPIC_API_KEY được đặt trong environment. Ở chế độ non-interactive, tức claude -p bên trong script hoặc cron job, sẽ không có prompt: key luôn được dùng nếu có mặt.

Làm thế nào để tìm ANTHROPIC_API_KEY bị sót trên VPS?

Trước tiên, xác nhận biến này tồn tại trong shell mà bạn dùng để khởi chạy Claude Code.

env | grep -i anthropic

Sau đó chạy lệnh sửa lỗi trên trang xử lý sự cố của Anthropic. Lệnh này đồng thời là phép kiểm tra:

unset ANTHROPIC_API_KEY
claude

Nếu Claude Code khởi động và /status hiện subscription của bạn, bạn đã xác nhận nguyên nhân. Biến này xuất hiện lại trong shell tiếp theo vì unset chỉ thay đổi shell nơi bạn đã nhập lệnh. Phần còn lại của mục này tập trung vào việc tìm nơi đặt biến đó.

Profile của shell và các file environment toàn hệ thống

grep -rn ANTHROPIC ~/.bashrc ~/.bash_profile ~/.profile ~/.zshrc \
  ~/.config/fish/config.fish /etc/environment /etc/profile /etc/profile.d/ 2>/dev/null

Trang của Anthropic nêu ~/.zshrc, ~/.bashrc~/.profile. Trên server, hãy mở rộng phạm vi tìm kiếm. /etc/environment được PAM (pluggable authentication modules) đọc khi đăng nhập cho mọi user trên máy. Vì vậy, key do một đồng nghiệp đặt có thể xuất hiện trong session của bạn. Các file trong /etc/profile.d/ được chạy bởi login shell. Lưu ý rằng .bashrc chỉ được shell tương tác đọc, nên nó không thể giải thích lỗi bên trong một systemd service. File cần kiểm tra phụ thuộc vào cách Claude Code được khởi chạy.

systemd unit

Một unit không đọc profile của shell. Environment của nó đến từ các dòng Environment=EnvironmentFile= trong unit cũng như mọi drop-in.

systemctl cat claude-agent.service
systemctl show -p Environment claude-agent.service

systemctl cat in file unit, sau đó là mọi drop-in trong /etc/systemd/system/claude-agent.service.d/. Đây thường là nơi chứa override. systemctl show -p Environment in environment mà systemd thực sự sẽ truyền cho process. Với service chạy dưới user của bạn, thêm --user vào cả hai lệnh. Sau khi sửa unit, chạy sudo systemctl daemon-reload rồi restart service. Environment được tạo khi process khởi động và process đang chạy sẽ giữ bản sao đã nhận.

Session tmux và screen còn tồn tại sau khi bạn sửa cấu hình

Đây là nguyên nhân khiến nhiều người mất hàng giờ. tmux server giữ environment tại thời điểm nó được khởi động. Các pane mới kế thừa environment từ server, không phải từ shell hiện tại. Bạn xóa export khỏi .bashrc, mở pane mới nhưng key cũ vẫn còn.

tmux show-environment | grep -i ANTHROPIC
tmux set-environment -r ANTHROPIC_API_KEY

set-environment -r đánh dấu tên biến cần xóa khỏi environment mà tmux truyền cho process mới. Thêm -g cũng thực hiện việc tương tự với global environment của server. Các pane đã mở vẫn giữ bản sao riêng vì environment của process chỉ có thể thay đổi từ bên trong process đó. Sau khi xóa export, cách đáng tin cậy là detach, chạy tmux kill-server rồi tạo session mới. screen hoạt động tương tự. Bạn nên biết điều này trước khi thiết lập session Claude Code chạy lâu dài trong tmux trên VPS, vì loại session này thường tồn tại qua nhiều lần sửa cấu hình.

Để đọc environment của một process đang chạy, hãy yêu cầu kernel cung cấp:

tr '\0' '\n' < /proc/$(pgrep -n claude)/environ | grep -i anthropic

Lệnh này in các giá trị process nhận tại thời điểm exec, tức là các giá trị process thực sự đang dùng. Bạn phải là chủ sở hữu process hoặc root mới đọc được file đó. pgrep -n claude chọn kết quả mới nhất, nên hãy kiểm tra PID nếu có nhiều process đang chạy.

Docker và Compose

docker exec claude-agent env | grep -i anthropic
docker compose config

Lệnh đầu tiên hiển thị environment bên trong container đang chạy, bao gồm các giá trị từ --env-file, block environment: hoặc dòng ENV được tích hợp sẵn trong image. docker compose config in file compose sau khi đã resolve các biến, nên bạn thấy giá trị sẽ được truyền thay vì placeholder ${ANTHROPIC_API_KEY} đã viết. Cả hai lệnh đều in secret ra terminal, vì vậy hãy chạy chúng trong session mà bạn có thể xóa nội dung. Compose cũng tự động nạp file .env nằm cạnh file compose nếu không được chỉ định khác. Đây thường là nguồn của key mà không ai nhớ đã thêm.

File settings tồn tại sau mọi lần sửa shell

File settings của Claude Code chứa block env. Tài liệu nêu rõ xung đột: khi cùng một biến được đặt trong shell và block env của file settings, giá trị trong file settings được ưu tiên. Key được ghi ở đó sẽ ghi đè mọi unset bạn nhập.

grep -rn ANTHROPIC ~/.claude/settings.json .claude/settings.json .claude/settings.local.json 2>/dev/null

Hãy kiểm tra cả file của project và file của user. .claude/settings.json thường được commit nên được chia sẻ với mọi người clone repository. Tổ chức cũng có thể đẩy managed settings, và các settings này được ưu tiên hơn file của bạn. Nếu tìm thấy một key không thể xóa, hãy hỏi quản trị viên của tổ chức.

Nhánh còn lại: key thực sự sai

Nếu /status hiển thị một API key và đó đúng là điều bạn mong đợi, hãy xem lỗi này đúng theo nội dung của nó. Tài liệu tham chiếu lỗi của Anthropic nêu các nguyên nhân sau cho Invalid API key:

  • Key bị sai định dạng hoặc không chính xác.
  • Key đã bị thu hồi hoặc hết hạn.
  • Key thuộc về tổ chức hoặc tài khoản khác.

Kiểm tra giá trị mà không in nó vào scrollback:

echo "len=${#ANTHROPIC_API_KEY} tail=${ANTHROPIC_API_KEY: -6}"

Độ dài lớn hơn dự kiến một hoặc hai ký tự thường có nghĩa là newline ở cuối hoặc dấu quote đã bị đưa vào khi copy paste, hoặc do $(cat keyfile) đã giữ lại newline ở cuối file. Giá trị này được gửi trong header X-Api-Key, nên một ký tự thừa có nghĩa là credential được gửi không phải key bạn đã tạo.

Kiểm tra ANTHROPIC_AUTH_TOKEN trong cùng output vì nó nằm phía trên API key theo thứ tự. Một bearer token còn sót lại từ lần thử proxy có nghĩa là key bạn đang sửa hoàn toàn không phải credential được gửi đi. Cũng nên đọc ANTHROPIC_BASE_URL trong output đó, vì một giá trị cũ có thể trỏ client đến một gateway không còn tồn tại. Để hiểu tổng quan ở cấp header, xem cách xác thực API key của Anthropic hoạt động để biết mỗi giá trị đó mang thông tin gì. Trước khi quyết định máy này nên lưu credential nào, xem sự khác biệt giữa đăng nhập bằng subscription và API key để nắm bối cảnh.

Lỗi này không phải vấn đề về capacity. Nếu session xác thực thành công rồi các request mới fail trong lúc đang hoạt động, bạn đang gặp lỗi model quá tải, và không cần thay đổi credential.

Vì sao script apiKeyHelper của tôi bị lỗi?

apiKeyHelper là một key cấu hình dùng để chỉ định script mà Claude Code chạy để lấy credential. Tính năng này phù hợp với token được rotate hoặc token có thời hạn ngắn, chẳng hạn key được lấy từ vault. Contract này đơn giản: ghi key hiện tại vào standard output và thoát thành công. Tài liệu cho biết nếu script thoát với lỗi, bị timeout hoặc không ghi gì ra output thì các request sẽ fail với Your apiKeyHelper script is failing trong vòng ba lần thử.

Chạy script thủ công và kiểm tra cả hai phần của contract:

out=$(/usr/local/bin/anthropic-key.sh)
echo "exit=$? len=${#out} tail=${out: -6}"

Thoát với mã khác 0 là lỗi, ngay cả khi key đã được in chính xác. Helper in Fetching credential... vào standard output trước key cũng là lỗi, vì dòng đó sẽ trở thành một phần của credential. Hãy ghi thông báo tiến trình vào standard error.

Sau đó kiểm tra theo cách service sẽ chạy script:

env -i HOME="$HOME" PATH=/usr/bin:/bin /usr/local/bin/anthropic-key.sh
echo "exit=$?"

env -i khởi chạy script với environment gần như rỗng. Helper gọi aws, vault hoặc gcloud từ một thư mục mà .bashrc thêm vào PATH sẽ chạy khi bạn kiểm tra thủ công nhưng fail khi chạy thực tế, vì process Claude Code đang chạy chưa đọc .bashrc của bạn. Hãy bảo đảm script có quyền execute và mọi lệnh mà script gọi đều dùng đường dẫn tuyệt đối, hoặc tự đặt PATH bên trong script.

Hai hành vi khác được tài liệu mô tả cũng quan trọng trên server. Theo mặc định, Claude Code chạy lại helper sau 5 phút, còn CLAUDE_CODE_API_KEY_HELPER_TTL_MS đặt một khoảng thời gian khác. Vì vậy, nếu cấu hình chạy được lúc khởi động nhưng hỏng sau một giờ, lỗi xảy ra khi refresh chứ không phải lúc launch. Nếu helper mất hơn 10 giây để trả về key, Claude Code sẽ hiển thị cảnh báo trong prompt bar cùng thời gian đã trôi qua. Cảnh báo này cho biết lần gọi đang chậm, không phải đã hỏng. Đây là dấu hiệu sớm trước khi timeout chuyển thành lỗi.

Bạn có thực sự muốn đặt API key trên máy này không?

Cách xử lý không phải lúc nào cũng là xóa key. Hãy giữ key nếu máy cần được tính phí riêng:

  • Một agent không cần tương tác chạy trên VPS được tính phí cho Console sẽ không dùng hạn mức subscription của một người.
  • Các lần chạy không tương tác, khi claude -p không có terminal để phê duyệt và luôn dùng key nếu key tồn tại.
  • Máy không được liên kết với subscription nào.
  • Máy dùng chung hoặc máy của khách hàng, nơi tuyệt đối không nên lưu thông tin đăng nhập subscription cá nhân.

Chi phí thường là yếu tố quyết định. Bạn có thể xem so sánh giá API và subscription để quyết định.

Hãy xóa key nếu máy thuộc quyền quản lý của bạn và subscription là dịch vụ bạn đã trả phí. Sau đó, hãy bảo đảm key không quay lại. Thay vì export key trong ~/.bashrc, nơi mọi interactive shell đều kế thừa biến này, hãy chỉ cấp key cho service cần nó:

[Service]
EnvironmentFile=/etc/claude-agent.env

Giữ file đó ở mode 600 và đặt owner là user chạy service. Các phiên interactive của bạn sẽ không nhìn thấy file này. Vì vậy, claude của bạn vẫn dùng subscription, còn service tiếp tục dùng key. Nếu cần thông tin xác thực subscription trên máy không có browser, claude setup-token sẽ in OAuth token để bạn dán vào CLAUDE_CODE_OAUTH_TOKEN. Hãy nắm rõ các giới hạn được tài liệu mô tả trước khi phụ thuộc vào cách này: token chỉ có thể gửi model request, nên không dùng được Remote Control session và connector của claude.ai. Quyết định một lần cho từng máy và ghi quyết định đó vào unit file sẽ ngăn lỗi mà trang này đề cập, vì lỗi bắt đầu từ một key mà không ai nhớ đã thiết lập. Giới hạn những gì credential đó có thể truy cập sau khi được cấu hình là một việc khác, được trình bày trong chạy Claude Code an toàn trên VPS.

Một lưu ý trước khi bạn dùng biện pháp mạnh. /logout xóa credential đã lưu. Tài liệu cũng lưu ý rằng lệnh này xóa cả thông tin đăng nhập MCP (model context protocol) server và secret của plugin đã lưu. Vì vậy, bạn sẽ phải xác thực lại các thành phần đó sau đó.

FAQ

Vì sao Claude Code báo API key không hợp lệ dù tôi đã trả phí thuê bao?

Vì một ANTHROPIC_API_KEY trong environment được ưu tiên hơn đăng nhập bằng thuê bao. Tài liệu của Anthropic cho biết key được đặt trong environment sẽ được dùng thay cho thuê bao Pro, Max, Team hoặc Enterprise, ngay cả khi bạn đã đăng nhập. Ở chế độ non-interactive với -p, key này luôn được dùng nếu tồn tại. Chạy /status bên trong Claude Code để xem session đã chọn credential nào. Nếu xuất hiện dòng API key mà bạn không chủ động đặt key, hãy chạy unset ANTHROPIC_API_KEY rồi khởi động lại claude để xác nhận nguyên nhân.

Chạy /login có sửa được lỗi API key không hợp lệ không?

Không, nếu biến đó vẫn được đặt. /login ghi credential OAuth của thuê bao, nhưng credential này nằm cuối thứ tự ưu tiên credential của Claude Code, sau các environment variable và sau apiKeyHelper. Quá trình đăng nhập vẫn thành công nhưng credential đó bị bỏ qua, nên đăng nhập lại không thay đổi gì. Hãy xóa biến khỏi nơi đã đặt nó, hoặc tắt nút "Use custom API key" trong /config. Theo tài liệu, nút này chỉ xuất hiện khi ANTHROPIC_API_KEY được đặt trong environment.

Làm cách nào để biết Claude Code đang dùng phương thức xác thực nào?

Chạy /status trong session. Tài liệu mô tả dòng Login method cho biết tài khoản thuê bao của bạn và dòng API key xuất hiện khi đang dùng API key. So sánh kết quả đó với env | grep -i anthropic trong cùng shell mà bạn dùng để khởi chạy. Nếu một service hoặc container chạy Claude Code, hãy đọc environment của process bằng tr '\0' '\n' < /proc/<pid>/environ, vì process đang chạy giữ environment được cấp lúc khởi động, không phải environment của shell hiện tại.

Script apiKeyHelper của tôi chạy được khi tôi tự chạy. Vì sao Claude Code vẫn lỗi?

Thông thường nguyên nhân là environment hoặc exit status. Claude Code chạy helper từ process riêng, process này chưa từng đọc shell profile của bạn. Vì vậy, helper phụ thuộc vào một entry PATH từ .bashrc có thể lỗi khi chạy trong Claude Code nhưng vẫn hoạt động trong terminal của bạn. Kiểm tra bằng env -i HOME="$HOME" PATH=/usr/bin:/bin /path/to/helper rồi kiểm tra echo $? sau đó. Tài liệu liệt kê các trường hợp lỗi gồm script thoát với lỗi, hết thời gian chờ hoặc không in ra gì; lỗi này được hiển thị dưới dạng Your apiKeyHelper script is failing. Mọi nội dung được in ra standard output ngoài key đều trở thành một phần của credential. Vì vậy, hãy gửi các thông báo tiến trình vào standard error.