HTTP 401エラーの意味と解決方法|401 Authorization Requiredとは
ポイント
HTTP 401 Unauthorizedは、サーバーが「あなたが誰か」の証明を求めているのに、リクエストがそれを示さなかったか、拒否される認証情報を使ったことを意味します。「401 Authorization Required」は同じコードをnginxのデフォルトページで表示したもので、たいていはパスワードで保護されたエリアです。訪問者は正しい情報で再ログインする、サイトのCookieを削除する、またはサイトの管理者にアクセスを依頼してください。開発者はAuthorizationヘッダー(「Bearer <token>」)、キーやトークンの有効期限、WWW-Authenticateヘッダーが何を求めているかを確認してください。
今すぐ確認

読み始める
- 401 Unauthorizedエラーとは?
- 401エラーの表示例
- nginxの「401 Authorization Required」とは
- 401と403の違いとは?
- 401エラーの一般的な原因
- 訪問者としての401エラーの解決方法
- 1. ログイン認証情報を確認する
- 2. ブラウザのキャッシュとCookieをクリアする
- 3. シークレットモードまたはプライベートモードで試す
- 4. URLを確認する
- 開発者としての401エラーの解決方法
- 5. Authorizationヘッダーを確認する
- 6. APIキーの有効性を確認する
- 7. トークンの有効期限切れとリフレッシュに対応する
- 8. CORSプリフライトの問題を修正する
- サイト管理者としての401エラーの解決方法
- 9. サーバーの認証設定を確認する
- 10. .htaccessの認証ルールを確認する
- 11. Authorizationヘッダーがアプリまで届いているか確認する
- HTTPヘッダーを使った401エラーのデバッグ
- 401エラーはSEOに影響するか?
- 401エラーを防止する方法
- よくある質問
401 Unauthorizedエラーとは?
401 Unauthorizedエラーは、サーバーが「あなたが誰か」の証明を求めているのに、リクエストがそれを示さなかったか、送った認証情報が拒否されたことを意味します。 パスワードがない、パスワードが違う、トークンの期限が切れている、APIキーがない。どれも結果は同じです。
HTTPの標準仕様は、401を「対象リソースに対する有効な認証情報がない」リクエストと定義しています。401を返すサーバーは、受け付けるログイン方式を示すWWW-Authenticateヘッダーを必ず含めなければなりません(RFC 9110 §15.5.2)。
簡単に言えば、サーバーは中に入れる前に「あなたは誰ですか?」と尋ねているのです。
URLのステータスコードとWWW-Authenticateヘッダーを確認
401エラーの表示例
表示されるページは、サーバーやアプリによって異なります。
- 401 Unauthorized — 標準のステータス行で、ほとんどのアプリもこの表記です
- 401 Authorization Required — nginxに組み込まれた401ページのタイトルで、その下に「nginx」(通常はバージョン付き)と表示されます(nginxのソースコード)。古いApache 2.2のサーバーも同じ文言を使います
- Unauthorized · This server could not verify that you are authorized to access the document requested — Apacheのデフォルトページ
- 401 - Unauthorized: Access is denied due to invalid credentials — IIS。詳細なエラーページ(サーバー上でだけ表示されます)とIISのログには、理由が401.1、401.2、401.3として記録されます。それぞれログオンの失敗、サーバーの設定、ファイルのアクセス許可が原因です
- ブラウザのログイン画面 — サーバーがHTTP BasicまたはDigest認証を求めたとき、あるいは(IISや社内イントラネットで)NTLMやNegotiateを求めたとき
- このページは動作していません · HTTP ERROR 401 — 401レスポンスに独自のページがないときのChrome(日本語版の表示)
- APIからのJSON。例:
{"error":{"message":"Missing Authentication header","code":401}}
ブラウザがログイン画面を出すのは、これらのログイン方式のときだけです。トークンを使うAPI(「Bearer」)では表示されず、401はアプリが処理するJSONとして返ってきます。ログインフォームのあるWebサイトは、ログアウト状態の訪問者に401を返すのではなく、302リダイレクトでログインページへ移動させるのが一般的です。
nginxの「401 Authorization Required」とは
このタイトルは、nginxに組み込まれた401ページのものです。auth_basicで保護されたlocationに、ユーザー名とパスワードを付けずに、または間違った組み合わせでアクセスしたときに表示されます。ブラウザのログイン画面でキャンセルを押したときも、このページになります。
訪問者の場合は、ページを再読み込みして、サイトの管理者から渡されたユーザー名とパスワードを入力してください。これはサイト上のアカウントとは別物です。Basic認証は、サーバー上のパスワードファイルと照合しています。
サイトの管理者向けに、保護の設定方法と、特定のパスを誰でも見られるようにする方法を示します。
# Create the password file (htpasswd comes with apache2-utils or httpd-tools)
# sudo htpasswd -c /etc/nginx/.htpasswd alice # -c creates the file: leave it out when adding users
location /admin/ {
auth_basic "Admin area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
# Inside a protected server block, open one path to everyone
location /public/ {
auth_basic off;
}
# Test, then reload
# curl -I -u alice:PASSWORD https://example.com/admin/
# sudo nginx -t && sudo systemctl reload nginx正しいパスワードでも401になる場合は、そのユーザーがファイルに登録されているか(htpasswd -cはファイルを上書きするため、以前のユーザーが消えます)、nginxの後ろにあるアプリもAuthorizationヘッダーを必要としていないかを確認してください。nginxのBasic認証とアプリのBearerトークンはどちらも同じヘッダーを使うため、アプリにはnginx用の認証情報が届き、アプリがそれを拒否します。
401と403の違いとは?
401と403はよく混同されます。要するに、401は「あなたが誰か分からない」、403は「身元が問題かどうかにかかわらず、中には入れない」という意味です。
| 項目 | 401 Unauthorized | 403 Forbidden |
|---|---|---|
| 本質的な意味 | 認証の失敗または未提供 | 認可の拒否 |
| サーバーの質問 | 「あなたは誰ですか?」 | 「アクセス権限がありません」 |
| 認証情報 | 未提供または無効 | 有効だが権限不足、または無関係(IPブロック、ファイアウォール、ファイルのアクセス許可) |
| 再試行で解決する? | はい、正しい認証情報を使えば | 同じ認証情報では解決しない |
| WWW-Authenticateヘッダー | 仕様上は必須(省略するAPIも多い) | 任意(例:Bearer error="insufficient_scope") |
| シナリオ例 | ログインせずに管理パネルにアクセス | 閲覧者としてログインし、投稿を削除しようとする |
実用的なルール:正しいユーザー名とパスワード(またはAPIキー)を提供すれば解決する場合、サーバーは401を返すべきです。ユーザーがすでに認証済みだが、そのリソースへのアクセス権がない場合、サーバーは403 Forbiddenを返すべきです。
401エラーの一般的な原因
原因を、訪問者側からサーバー側の順に並べます。
- ユーザー名またはパスワードの間違い — 最も基本的な原因で、パスワードをリセットした直後に特に多く見られます
- 認証トークンの有効期限切れ — JWTトークン、OAuthアクセストークン、セッションCookieにはすべて有効期限があります
- Authorizationヘッダーの欠落 — リクエストに認証情報がまったく含まれていない
- 無効なAPIキー — キーが取り消された、ローテーションされた、またはコピーを間違えた
- 認証方式の不一致 — サーバーはBearerトークンを期待しているのにBasic認証が送られた(またはその逆)
- クロックスキュー(時刻のずれ) — JWTを検証するサーバーと発行したサーバー(JWTに署名するのが自分のマシンならそのマシン)の時刻が合っていない。多くのライブラリは猶予をまったく設けていません
- CORSプリフライト — ブラウザのOPTIONSによる事前確認は認証情報を一切送らないため、認証を必須にしているサーバーは401を返し、本来のリクエストは送信されません
- 古いセッション — サーバー側ですでに終了したセッションのCookieを、ブラウザが送り続けている
- 途中の何かがヘッダーを落としている — Apacheは設定しない限りPHP-FPMやCGIスクリプトにAuthorizationを渡さず、CloudFrontはデフォルトでGETとHEADのリクエストからこのヘッダーを取り除き、アプリの前に置いたnginxのBasic認証はこのヘッダーを横取りします
- ロックまたは失効した認証情報 — ログインの失敗が続くとアカウントがロックされることがあります(これを429 Too Many Requestsで返すAPIもあります)
訪問者としての401エラーの解決方法
ウェブサイトにアクセスしようとして401エラーが表示された場合、問題はほぼ確実にログイン認証情報に関連しています。以下の手順を順番に実行してください。
1. ログイン認証情報を確認する
401エラーの最も一般的な原因は、単純に認証情報の間違いです。サイトにログインポップアップやフォームが表示された場合、ユーザー名とパスワードを再確認してください。
よくある間違い:Caps Lockがオンになっている、古いパスワードを使用している(特に最近リセットした後)、間違ったアカウントにログインしようとしている。パスワードマネージャーを使用している場合は、入力ミスを避けるために自動入力を使用してください。
2. ブラウザのキャッシュとCookieをクリアする
ブラウザが期限切れのセッションCookieを送っている可能性があります。そのサイトのCookieを削除すると、改めてログインを求められるようになります。
日本語版のChromeでは、Ctrl+Shift+Delete(MacはCmd+Shift+Delete)で「閲覧履歴データを削除」を開き、「期間」を「全期間」にして「Cookie と他のサイトデータ」と「キャッシュされた画像とファイル」を選び、「データを削除」を押します。これですべてのサイトからログアウトされるので、1つのサイトだけを消すなら、アドレスバー左のアイコン(「サイト情報を表示」)→「サイトの設定」→「データを削除」を使ってください。下の手順は英語版の表示です。
Chrome, Edge, Firefox: Ctrl+Shift+Delete (Cmd+Shift+Delete on a Mac)
→ Time range: All time → Cookies and site data + Cached files → Delete / Clear
(this signs you out of every site; the per-site option below doesn't)
Safari: Settings → Privacy → Manage Website Data → the site → Remove
One site in Chrome: the icon left of the address → Site settings → Delete dataクリア後、ブラウザを完全に閉じ(タブだけでなく)、再度開いてページにアクセスしてください。新しいログインプロンプトが表示されるはずです。
3. シークレットモードまたはプライベートモードで試す
URLを、Chromeのシークレット ウィンドウ(メニューの「新規シークレット ウインドウ」)、Firefoxの「新しいプライベートウィンドウ」、Safariのプライベートブラウズで開いてください。キャッシュされたCookie、拡張機能、保存された認証情報をすべて避けて開けます。
シークレットモードではページが動作するが通常のブラウザでは動作しない場合、問題はキャッシュされたCookieか、認証を妨げるブラウザ拡張機能です。拡張機能を一つずつ無効にして原因を特定してください。
4. URLを確認する
正しいURLにアクセスしていることを確認してください。一部のサーバーは、パス自体が間違っている場合でも、認証が必要なパスに対して401を返します。アクセスするべきでない制限エリアにアクセスしようとしている可能性があります。
別のURLにページの公開バージョンがないか確認してください。例えば、example.com/admin/は401を返しますが、example.com/は公開アクセス可能な場合があります。
そもそもサイトが動いているか分からない場合は、サーバーダウンチェックが11か所からサイトを開くので、ログインの問題なのか障害なのかを切り分けられます。
開発者としての401エラーの解決方法
APIを扱う開発者の場合、401エラーは通常、Authorizationヘッダー、トークンの形式、または認証情報のライフサイクルに関する問題です。以下は最も一般的な修正方法です。
5. Authorizationヘッダーを確認する
開発者に最も多いミスは、Authorizationヘッダーの形式の誤りです。サーバーがWWW-Authenticateヘッダーを返す場合は、そこに期待する方式が書かれています。ただし多くのJSON API(GitHubやOpenRouterなど)はこのヘッダーを省き、代わりにレスポンスボディで問題を説明します。
ヘッダーが要求される形式と一致していることを確認してください。最も一般的なスキームは、Bearer(トークン用)とBasic(Base64エンコードされたユーザー名:パスワード用)です。
# Bearer token authentication (most APIs)
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." https://api.example.com/data
# Basic authentication (username:password in Base64)
curl -u "username:password" https://api.example.com/data
# Equivalent to:
curl -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" https://api.example.com/data
# Common mistakes that cause 401:
# Missing "Bearer " prefix: Authorization: eyJhbGci... ← WRONG
# Extra space: Authorization: Bearer eyJ... ← many servers reject it
# Wrong scheme: Authorization: Basic eyJhbGci... ← WRONGそのうえで、401レスポンスのWWW-Authenticateヘッダーを読んでください。サーバーが期待する方式が書かれています。DNS RobotのHTTPヘッダーチェッカーでレスポンス全体を確認できます。
6. APIキーの有効性を確認する
APIキーが使えなくなるのは、キーがローテーションまたは取り消されたとき、アカウントが停止またはダウングレードされたとき、テスト用のキーを本番環境で使ったときです。(レート制限なら429が返り、エンドポイントへのアクセスを許可されていないキーには通常403が返ります。)
プロバイダーのダッシュボードでキーがまだ有効か確認してから、次のように直接テストしてください。
# Test a key: print only the status code (a real GET; some APIs reject HEAD)
curl -s -o /dev/null -w "%{http_code}\n" -H "Authorization: Bearer YOUR_API_KEY" https://api.example.com/me
# 200 = the key works
# 401 = the key is missing, wrong, revoked or expired
# 403 = the key works but isn't allowed to use this endpoint
# Common slips:
# 1. A space or newline after the key in .env: API_KEY="abc123 "
# 2. The test key in production, or the reverse
# 3. An empty variable, so the header is just "Authorization: Bearer"7. トークンの有効期限切れとリフレッシュに対応する
JWTトークンとOAuthアクセストークンには有効期間が設定されており、通常は15分から24時間です。有効期限が切れると、新しいトークンを取得するまで、すべてのAPI呼び出しが401を返します。
リフレッシュトークンがある場合(OAuth 2.0とほとんどのJWT構成)は、それを新しいアクセストークンと交換してください。ない場合は、もう一度ログインします。
# Read a JWT's payload (tokens use base64url, so plain base64 -d often fails)
python3 -c 'import sys,base64,json; p=sys.argv[1].split(".")[1]; print(json.dumps(json.loads(base64.urlsafe_b64decode(p+"==")),indent=2))' "$TOKEN"
# "exp" is a Unix timestamp; compare it with: date +%s
# OAuth 2.0: get a new access token with the refresh token
curl -X POST https://auth.example.com/token \
-d "grant_type=refresh_token" \
-d "refresh_token=YOUR_REFRESH_TOKEN" \
-d "client_id=YOUR_CLIENT_ID"8. CORSプリフライトの問題を修正する
WebページがAuthorizationヘッダー付きで別ドメインのAPIを呼び出すとき、ブラウザはまずプリフライトのOPTIONSリクエストを送ります。このプリフライトは認証情報を一切含みません。サーバーがOPTIONSにも認証を求めていると401を返し、プリフライトが失敗して、ブラウザはCORSエラーを表示します。本来のリクエストは送信されません。
修正方法:CORSを有効にしたエンドポイントでは、OPTIONSリクエストを認証なしで通してください。
# Nginx — allow OPTIONS requests without auth
location /api/ {
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin https://app.example.com;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Authorization, Content-Type";
add_header Access-Control-Max-Age 86400;
return 204;
}
# CORS header on every other answer, the 401 included, or the browser reports a CORS error
add_header Access-Control-Allow-Origin https://app.example.com always;
# Normal auth for other methods
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
}サイト管理者としての401エラーの解決方法
訪問者やユーザーから401エラーの報告がある場合、問題はサーバーの認証設定にあります。以下のチェック項目を順番に確認してください。
9. サーバーの認証設定を確認する
認証が必要なルートにのみ認証が有効になっていることを確認してください。よくある間違いは、特定のパスだけがログインを必要とするのに、ディレクトリ全体やサイト全体を保護してしまうことです。
nginxではauth_basicディレクティブを、ApacheではAuthTypeとRequireを確認してください。Node.js/Expressではミドルウェアの順序を確認します。公開ルートより前に登録したapp.use(auth)はそれらのルートまで保護してしまうので、公開ルートを先に登録するか、認証を保護対象のルーターだけに付けてください。
# Nginx — WRONG: protects everything, including public pages
server {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
# All pages now require login — including your homepage!
}
# Nginx — CORRECT: only protect admin routes
server {
location / {
# Public — no auth required
}
location /admin/ {
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}10. .htaccessの認証ルールを確認する
Apacheでは、.htaccessファイルでディレクトリにBasic認証やDigest認証をかけられます。公開ディレクトリの.htaccessにAuthTypeとRequireディレクティブがあると、すべての訪問者に401のログイン画面が表示されます。
影響を受けているディレクトリとすべての親ディレクトリに.htaccessファイルがないか確認してください。Apacheはパス内のすべての.htaccessのルールを適用します。
# Find all .htaccess files with auth rules
find /var/www/html -name '.htaccess' -exec grep -l 'AuthType\|AuthUserFile\|Require valid-user' {} \;
# Example .htaccess that causes 401 for everyone:
# AuthType Basic
# AuthName "Restricted Area"
# AuthUserFile /etc/apache2/.htpasswd
# Require valid-user
# Fix: remove auth lines from public directories,
# or move them to the specific /admin/.htaccess only11. Authorizationヘッダーがアプリまで届いているか確認する
クライアントは正しい認証情報を送っているのに、アプリには届いていないケースです。ヘッダーが失われる場所は次のとおりです。
nginxはデフォルトでAuthorizationをバックエンドに転送するので、追加の設定は不要です。ただし同じlocationでauth_basicを使っていると、nginxのログインがこのヘッダーを横取りします(上のnginxのセクションを参照)。Apacheは、CGIPassAuth(Apache 2.4.13以降)を有効にしない限り、PHP-FPMやCGIスクリプトにAuthorizationを渡しません。Apacheで動かしているWordPressやLaravelのAPIが401を返す、典型的な原因です。
# Apache 2.4.13+ (inside a <Directory> block, or .htaccess): pass Authorization to PHP-FPM and CGI
CGIPassAuth On
# Older Apache: copy it into an environment variable instead
SetEnvIf Authorization "(.+)" HTTP_AUTHORIZATION=$1HTTPヘッダーを使った401エラーのデバッグ
401を最も早く診断する方法は、レスポンスを読むことです。サーバーがWWW-Authenticateヘッダーを返していれば、どのログインを求めているかが分かります。JSON APIは通常、ボディでエラーを説明しています。
DNS RobotのHTTPヘッダーチェッカーを使うか(リダイレクトのあとでだけ401が出る場合は、リダイレクトチェッカーでどのホップが401を返しているか分かります)、ターミナルからcurlを使ってください。
# Print the response headers of a real GET
curl -sS -D - -o /dev/null https://api.example.com/protected-endpoint
# A 401 often carries one of:
# WWW-Authenticate: Bearer realm="api", error="invalid_token"
# WWW-Authenticate: Basic realm="Admin Area"
# It tells you:
# - the scheme (Bearer, Basic, Digest, Negotiate)
# - the realm (which area is protected)
# - for Bearer tokens, the error: invalid_request, invalid_token or insufficient_scopeWWW-AuthenticateがBearerならトークンが、Basicならユーザー名とパスワードが必要です。error="invalid_token"は、トークンが期限切れ、取り消し済み、形式不正、またはその他の理由で無効であることを示します。ヘッダーがまったくない場合は、レスポンスボディを読んでください。多くのAPIはそこに理由を書いています。
401エラーはSEOに影響するか?
公開ページが401を返すと、そのページはGoogleから外れます。Googleは429以外のすべての4xxコードを同じように扱い、クローラーはそのコンテンツが存在しないと報告して、インデックス済みのURLは削除されます(Googleのクローラーに関するドキュメント)。
ログインが必要なはずのページ(管理パネル、ダッシュボード、API)での401は正常で、Googleがそれを理由にサイトを不利に扱うことはありません。ただし、Googlebotのクロールを遅くする目的で401や403を使わないでください。Googleは、これらがクロール頻度に影響しないとしています。
問題になるのは、公開されるべきページで401が出る場合です。原因はたいてい、サイト全体にかけた認証や、公開パスで認証情報を求めるCDNやプロキシのルールです。
401エラーを防止する方法
予防は後のデバッグ作業を省きます。アプリケーションやウェブサイトでの401エラーを最小限に抑えるために、以下のプラクティスを実践してください。
- トークンの自動リフレッシュを実装する — リフレッシュトークンを使用して、有効期限が切れる前にサイレントに新しいアクセストークンを取得する
- 適切な認証スコープを設定する — 本当に認証が必要なルートのみを保護し、公開ページはオープンにする
- 明確なエラーメッセージを返す — ステータスコードだけでなく、役立つJSONエラーボディを401と一緒に返す
- 認証失敗を監視する — 401レスポンスの急増に対するアラートを設定する(認証情報の問題や攻撃を示す可能性がある)
- サーバーの時刻を同期する — NTPを使用してすべてのサーバーをUTCの数秒以内に保ち、JWTのクロックスキューによる拒否を防ぐ
- HTTPヘッダーチェッカーでテストする — 公開ページが200を、保護されたページが期待どおり401を返すことを定期的に確認する
- 認証スキームをドキュメント化する — 期待されるAuthorizationヘッダーの形式をAPIドキュメントで明確にする
- CORSプリフライトに対応する — APIエンドポイントでは常に認証なしでOPTIONSリクエストを許可する
401とWWW-Authenticateヘッダーを確認
DNS Robotの無料HTTPヘッダーチェッカーで、任意のURLのステータスコードとレスポンスヘッダーを確認できます。サーバーが期待するログイン方式を示すWWW-Authenticateも表示します。



