エラーの概要

Azure への API リクエストやコマンド実行時に 401 Unauthorized エラーが返される場合、認証情報が無効であるか期限切れになっていることを示しています。このエラーが発生すると、Azure リソースへのアクセスが完全にブロックされ、デプロイやリソース管理の操作が実行できなくなります。Azure CLISDK、マネージド ID など複数の認証方式で発生する可能性があります。

実際のエラーメッセージ例

Azure CLI での出力例:

$ az group list
ERROR: The command failed with an unexpected status code: 401 (Unauthorized).
The command failed with an error. (AuthenticationFailed) Authentication failed. The `Credentials` object was not initialized. Please call `Credentials.Initialize()` before making any requests.

REST API レスポンス例:

{
  "error": {
    "code": "AuthenticationFailed",
    "message": "Authentication failed. The user or application is not authorized to access the resource.",
    "details": [
      {
        "code": "Unauthorized",
        "message": "The request requires authentication information."
      }
    ]
  }
}

よくある原因と解決手順

原因1:az login のセッションが期限切れになっている

Azure CLI認証セッションには有効期限があります。特に長時間セッションを保持していたり、PC のスリープ後に再度コマンドを実行したりする場合、自動的にセッションが無効化されることがあります。

Before(エラーが起きるコード):

# 前回のセッションから時間が経過した状態で実行
$ az vm list --resource-group myResourceGroup
ERROR: The command failed with an unexpected status code: 401 (Unauthorized).

After(修正後):

# セッションを更新する
$ az login

# または、対話形式で再ログインする場合
$ az login --use-device-code

# その後、コマンドを実行
$ az vm list --resource-group myResourceGroup

az login コマンドを実行すると、ブラウザが起動して Azure ポータルへのログインが求められます。完了後、CLI セッションが更新され、その後のコマンドが正常に実行できるようになります。

原因2:サービスプリンシパルのシークレットが期限切れになっている

CI/CD パイプラインやスクリプト自動化でサービスプリンシパル認証を使用している場合、設定したシークレット(またはクライアントシークレット)の有効期限が切れると 401 エラーが発生します。Azure では セキュリティ上の理由から、デフォルトでシークレットに 1 ~ 2 年の有効期限が設定されます。

Before(エラーが起きるコード):

# 期限切れのシークレットで認証を試みる
$ az login --service-principal \
  -u <client-id> \
  -p <expired-client-secret> \
  --tenant <tenant-id>
ERROR: The command failed with an unexpected status code: 401 (Unauthorized).
Authentication failed. The credentials provided do not grant access to the resource.

After(修正後):

# 1. 新しいシークレットを生成する
$ az ad sp credential reset \
  --id <client-id> \
  --years 2

# 出力例:
# {
#   "appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
#   "password": "new-secret-value",
#   "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# }

# 2. 新しいシークレットで再度ログインする
$ az login --service-principal \
  -u <client-id> \
  -p <new-client-secret> \
  --tenant <tenant-id>

新しいシークレットを生成後、CI/CD 環境変数や自動化スクリプトに設定される秘密情報を更新することを忘れずに行ってください。

原因3:マネージド ID が有効になっていないリソースで使用しようとしている

Azure Virtual Machine、Azure Functions、App Service などのリソースでマネージド ID認証を使用する場合、対象のリソースでマネージド ID 機能が有効化されていないと 401 エラーが発生します。マネージド ID は Azure が自動的に管理する認証方式で、シークレット管理の手間を削減します。

Before(エラーが起きるコード):

# マネージドIDが無効なVMで実行される Python スクリプト
from azure.identity import ManagedIdentityCredential
from azure.storage.blob import BlobServiceClient

# マネージドIDが無効な場合、ここで 401 エラーが発生
credential = ManagedIdentityCredential()
blob_client = BlobServiceClient(
    account_url="https://<storage-account>.blob.core.windows.net",
    credential=credential
)
blobs = blob_client.list_blobs(container_name="mycontainer")
# ERROR: Azure Identity: ManagedIdentityCredential - Failed to get token. 
# Status code: 401

After(修正後):

# 1. Azure Portal で VM のマネージド ID を有効化
# または Azure CLI で実施:
$ az vm identity assign \
  --resource-group <resource-group> \
  --name <vm-name> \
  --identities [system]

# 2. ストレージアカウントのアクセス権限をマネージド ID に付与
$ az role assignment create \
  --role "Storage Blob Data Reader" \
  --assignee-object-id <managed-identity-principal-id> \
  --scope /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>

# 3. Python スクリプトは同じコードで動作するようになる
# (マネージドIDが有効になっているため、認証が成功)

Python スクリプト本体の修正は不要です。リソース側のマネージド ID 設定を有効化すれば、Azure SDK が自動的に認証を処理します。

ツール固有の注意点

Azure CLI の複数アカウント管理: 複数の Azure サブスクリプションやテナントにアクセスしている場合、az account show でアクティブなアカウントを確認し、az account set --subscription <subscription-id> で対象サブスクリプションに切り替えてください。誤ったアカウントで認証されている場合も 401 エラーが発生します。

環境変数による認証 AZURE_CLIENT_IDAZURE_CLIENT_SECRETAZURE_TENANT_ID などの環境変数を使用する場合、これらが正しい値で設定されているか確認してください。特に自動デプロイ環境では、環境変数の値が古いままになっていることが原因の 1 つです。

マネージド ID と Role-Based Access Control(RBAC)の組み合わせ: マネージド ID を有効化した後、リソースが実際にアクセスしたい対象(ストレージアカウント、キーボルト など)に対する RBAC ロールを割り当てる必要があります。マネージド ID の有効化だけでは権限が付与されないため注意が必要です。

それでも解決しない場合

Azure のアクティビティログを確認: Azure ポータルの「アクティビティログ」セクションで、失敗した操作の詳細を確認してください。具体的な認証エラーの理由が記録されていることがあります。

Azure SDK のデバッグログを有効化: Python や Node.js でログレベルを設定し、詳細な認証情報を出力します:

import logging
logging.basicConfig(level=logging.DEBUG)

from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()

このコマンドで、どの認証方式が試行され、どこで失敗しているかを特定できます。

公式ドキュメント参照: Azure 認証について詳しくは、Microsoft Learn の Azure 認証ガイド および Azure CLI ドキュメント を参照してください。


免責事項:本記事の内容は、執筆時点の公開情報をもとに作成したものです。ソフトウェアの仕様は予告なく変更されることがあります。最新の情報は各ツールの公式サポートページをご確認ください。本記事の情報を利用した結果生じたいかなる損害についても、著者および運営者は責任を負いかねます。