開発・運用で遭遇するエラーコードの原因と解決策を、ツール別にまとめたリファレンスです。
Firebase の 408 エラー:原因と解決策408
Firebase 408 エラーはクライアント側からのリクエストがタイムアウト時間内に完了できず、Firebase サーバーが接続を切断した状態です。ネットワーク環境またはアプリケーションの処理速度が原因となります。 よくある原因 ネットワーク接続の不安定性 WiFi や 4G 接続が途中で断絶したり、パケット損失が発生したりするとリクエストが完了されません。特に移動中のモバイル環境や、企業のファイアウォール経由でのアクセスでは接続が中断されやすくなります。Firebase サーバーはリクエスト到着を待ちますが、タイムアウト時間(デフォルト 30 秒程度)を超えると接続を切断し 408 を返します。 クライアント側の処理遅延 リクエスト送信前の処理(データベースクエリ、ファイル読み込み、画像圧縮など)が想定より長くかかると、タイムアウト発動前にエラーとなります。特に大容量データの同期や複雑な認証処理では、クライアント内での遅延が積み重なりやすいです。 Firebase クライアント SDK の設定不足 デフォルトのタイムアウト値がアプリケーション要件に合わず、処理時間が長いトランザクション(バッチ書き込みなど)で頻発します。 解決手順 ステップ 1:ネットワーク接続を確認する まずクライアント環境のネットワーク状態を確認します。WiFi 接続が不安定でないか、通信速度が著しく低下していないか確認してください。 Android 環境での確認例: ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting(); Log.d("Network", "接続状態: " + isConnected); Web 環境での確認例: // ネットワーク接続状態の確認 if (navigator.onLine) { console.log("オンライン状態"); } else { console.log("オフライン状態"); } ステップ 2:Firebase クライアント SDK のタイムアウト設定を延長する Android での設定例: FirebaseDatabase database = FirebaseDatabase.getInstance(); // タイムアウトを 60 秒に延長(デフォルト: 30秒) database.setLogLevel(Logger.Level.DEBUG); DatabaseReference ref = database.getReference(); // 接続タイムアウトの明示的な設定 ref.child("your-path").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { // 処理 } @Override public void onCancelled(DatabaseError error) { Log.e("Firebase", "エラーコード: " + error.getCode()); } }); Web(JavaScript)での設定例: ...
Firebase の 504 エラー:原因と解決策504
Firebase HostingまたはCloud Functionsのバックエンド処理がタイムアウトし、クライアントに504エラーが返される状況です。この記事では原因の特定と具体的な解決方法を解説します。 よくある原因 Cloud Functionsの処理時間がFirebase Hostingのタイムアウトを超えている Firebase HostingからCloud Functionsを呼び出す場合、Hostingの統合タイムアウト制限(通常60秒)内に関数が応答を返す必要があります。データベースクエリが遅い、外部APIの呼び出しが遅延している、複雑な計算処理が走っているなど、処理時間が長くなると504エラーが発生します。 コールドスタート時の初期化処理に時間がかかっている Cloud Functionsは関数が実行されていない状態から起動する際(コールドスタート)、メモリ確保、ライブラリの読み込み、データベース接続の初期化などの処理が発生します。この初期化処理がタイムアウト制限内に完了しないと504エラーになります。特にNode.jsで大量の依存ライブラリをインポートしている場合に顕著です。 外部サービスへの依存処理の遅延 Cloud Functionsから外部APIやサードパーティサービスを呼び出す場合、そのサービスの応答時間がFirebaseのタイムアウト制限を超えると504エラーになります。ネットワーク状況が悪い、外部サービスが過負荷状態である、タイムゾーン違いでレスポンスが遅くなるなどの原因が考えられます。 解決手順 手順1: Cloud Functionsのタイムアウト設定を確認・延長する Firebase Console(console.firebase.google.com)にアクセスし、プロジェクトを選択します。左メニューから「ビルド」→「Cloud Functions」を開き、該当の関数をクリックします。「トリガー」タブでタイムアウト値を確認し、必要に応じて変更します。 # コマンドラインでデプロイする場合、firebase.json で設定する gcloud functions deploy <関数名> \ --runtime nodejs18 \ --timeout=540s \ --memory=512MB \ --region=asia-northeast1 タイムアウト値は最大540秒(9分)まで延長できます。ただし処理が本当に長い場合は、後述の最適化を優先してください。 手順2: 初期化処理をグローバルスコープに移動しコールドスタートを高速化する Cloud Functionsでは、関数のハンドラ外(グローバルスコープ)に記述した処理はコールドスタート時に1回だけ実行され、以後のリクエストで再実行されません。データベース接続、ライブラリの初期化、認証情報の読み込みなどをグローバルスコープに移動します。 // 悪い例:毎回実行される exports.myFunction = functions.https.onRequest((req, res) => { const db = admin.database(); // 毎回初期化される const query = db.ref('users').orderByChild('age').limitToFirst(100); query.once('value').then(snapshot => { res.send(snapshot.val()); }); }); // 良い例:初期化は1回だけ const admin = require('firebase-admin'); admin.initializeApp(); const db = admin.database(); // グローバルスコープで1回だけ実行 exports.myFunction = functions.https.onRequest((req, res) => { const query = db.ref('users').orderByChild('age').limitToFirst(100); query.once('value').then(snapshot => { res.send(snapshot.val()); }); }); 手順3: 数分後に再試行する ...
GCP の 404 エラー:原因と解決策404
GCP で 404 エラーが表示される場合、指定したリソースが見つからないことを意味します。リソース名の誤りやプロジェクト・リージョンの不一致が主な原因です。 よくある原因 リソース名またはIDの綴りが間違っている GCP のリソースID(インスタンス名、バケット名、サービスアカウント名など)は大文字小文字を区別します。また、ハイフンとアンダースコアの混同、数字の誤入力もよくある原因です。API リクエストやコマンド実行時に誤ったリソース名を指定すると、システムが該当するリソースを見つけられず 404 エラーが返されます。 リソースが別のプロジェクトまたはリージョンに存在している GCP では同じリソース名でも複数のプロジェクトやリージョンに存在できます。別のプロジェクトで作成したリソースにアクセスしようとしたり、異なるリージョン(例:us-central1 と asia-northeast1)を指定して検索したりすると、現在のコンテキストでは見つかりません。 リソースがすでに削除されている 削除されたリソースへのアクセスや参照は 404 エラーになります。特にスクリプトやパイプラインの実行時に、削除完了の確認がないまま同じリソースに再度アクセスしようとするケースで発生しやすいです。 解決手順 ステップ 1: Google Cloud Console でプロジェクトとリージョンを確認する Google Cloud Console(https://console.cloud.google.com)にアクセスして、画面上部のプロジェクト選択ドロップダウンで正しいプロジェクトが選択されていることを確認します。次に、リソースのページ(Compute Engine、Cloud Storage、Cloud SQL など)を開き、画面上部またはフィルタセクションでリージョンが正しく設定されていることを確かめます。 ステップ 2: gcloud コマンドでリソース一覧を確認する 実際のリソースが存在するかどうか、以下のコマンドで確認します。 # Compute Engine インスタンスの場合 gcloud compute instances list --project=<your-project-id> --zones=<your-zone> # Cloud Storage バケットの場合 gcloud storage buckets list --project=<your-project-id> # Cloud SQL インスタンスの場合 gcloud sql instances list --project=<your-project-id> リソースが表示されれば、リソースIDと現在のプロジェクト・リージョンを確認します。 ステップ 3: API リクエストのパラメータを確認する ...
GCP の 429 エラー:原因と解決策429
GCP で 429 エラーが発生した場合、これはリクエストレート制限(Rate Limiting)に達したことを意味します。Google Cloud のサービス側がリクエスト数の上限に到達し、それ以上の処理を受け付けられない状態です。 よくある原因 ループ処理でAPIを呼び出す間隔を設けていない for ループや while ループの中で API を呼び出す際に、リクエスト間の待機時間(ウェイト)を設定していないと、数秒間に数千のリクエストが送信されます。GCP のクォータはプロジェクト単位で時間枠ごとに制限されているため、瞬間的な高頻度リクエストは即座にレート制限に引っかかります。 クォータが低いAPIを高頻度で実行している Google Cloud のすべての API に等しいクォータが割り当てられているわけではありません。例えば Cloud Vision API や Cloud Translation API は、デフォルトのクォータが比較的低く設定されています。これらのAPI を大量のデータに対して実行すると、数分でクォータを消費し切ってしまいます。 複数のサービスが同じプロジェクトのクォータを共有して消費している 1つのプロジェクト内で複数のマイクロサービスやバッチ処理ジョブが並行して同じ API を呼び出している場合、クォータは各サービスで共有されます。一つのサービスが高頻度でリクエストを送ると、他のサービスのリクエストが拒否される可能性があります。 解決手順 1. Google Cloud Console でクォータを確認する まずどのAPIのクォータに到達したかを特定します。 Google Cloud Console(https://console.cloud.google.com)にアクセスします 左側のメニューから「IAMと管理」→「クォータと上限」を選択します 該当するサービス(例:Cloud Vision API、Compute Engine API)を検索します 「現在の利用状況」列でクォータの消費状況を確認します 上限に近い数値が表示されている API が 429 エラーの原因です 2. リトライ処理に指数バックオフを実装する 短期的な対策として、クライアント側でリトライロジックを追加します。429 エラーが返された時に、指数的に待機時間を増やしながら再試行します。 import time from google.api_core.gapic_v1 import client_info from google.cloud import vision import google.api_core.exceptions def call_api_with_backoff(func, max_retries=5): """指数バックオフ付きのAPIリトライ関数""" retry_count = 0 wait_time = 1 # 初回の待機時間は1秒 while retry_count < max_retries: try: return func() except google.api_core.exceptions.TooManyRequests: # 429 エラーをキャッチ if retry_count >= max_retries - 1: raise print(f"レート制限に達しました。{wait_time}秒待機します...") time.sleep(wait_time) wait_time *= 2 # 次回の待機時間を2倍にする retry_count += 1 # 使用例 client = vision.ImageAnnotatorClient() def analyze_image(): # APIの呼び出し処理 return client.batch_annotate_images(requests) result = call_api_with_backoff(analyze_image) または Python の tenacity ライブラリを使用することもできます。 ...
GCP の 500 エラー:原因と解決策500
GCP(Google Cloud Platform)で500エラーが返される場合、これはGoogle Cloud側の内部的な問題を示しており、ほとんどのケースでは利用者側の設定では解決できません。 よくある原因 Google Cloud内部の予期しないエラー GCP側のサーバーやサービスで予期しないエラーが発生している状態です。このエラーが返される時点で、リクエストはGoogleのサーバーに到達していますが、処理途中で想定外の問題(メモリリーク、デッドロック、内部バグなど)が発生しています。利用者側のAPIキー設定、認証情報、リクエスト形式はすべて正しいにもかかわらず、Google側のシステムが適切に応答できない状態です。 一時的なサービス障害 GCPの各サービス(Compute Engine、Cloud Storage、Cloud SQL、BigQuery等)は複数のサーバーで冗長構成されていますが、ローリングアップデート、メンテナンス、または予期しないインフラの問題によって、リクエストを処理するサーバーが一時的に利用不可になることがあります。その結果、500エラーが返されます。 解決手順 ステップ1:Google Cloud Status Dashboardで障害情報を確認する まず、GCP全体の障害状況を把握します。 https://status.cloud.google.com/ このページにアクセスして、対象のサービス(例:Compute Engine、Cloud Storage)に赤いインシデントアイコンが表示されていないか確認します。黄色は軽微な問題、赤は重大な障害を示します。障害が報告されている場合は、復旧を待つしかありません。 ステップ2:数分後に再試行する(指数バックオフ戦略) 一時的なエラーの可能性が高いため、即座に同じリクエストを送信するのではなく、待機してから再試行します。コード内に指数バックオフ機構を実装してください。 import time import requests from google.auth.transport.requests import Request from google.oauth2 import service_account # 認証情報の準備 credentials = service_account.Credentials.from_service_account_file( '<path-to-service-account-key>.json' ) url = 'https://compute.googleapis.com/compute/v1/projects/<your-project-id>/zones/asia-northeast1-a/instances' # 指数バックオフで再試行 max_retries = 5 retry_count = 0 wait_seconds = 1 while retry_count < max_retries: try: headers = {'Authorization': f'Bearer {credentials.token}'} response = requests.get(url, headers=headers, timeout=10) if response.status_code == 500: retry_count += 1 print(f'500エラーを受信。{wait_seconds}秒後に再試行します...') time.sleep(wait_seconds) wait_seconds *= 2 # 次の待機時間を2倍にする else: print(f'成功: {response.status_code}') break except Exception as e: print(f'リクエスト失敗: {e}') break if retry_count == max_retries: print('最大再試行回数に達しました。Google Cloud Supportに連絡してください。') ステップ3:Google Cloud Console上でも同じエラーが発生するか確認する ...
GCP の 503 エラー:原因と解決策503
GCP(Google Cloud Platform)で503エラーが発生した場合、Google Cloudサービス側が一時的に利用できない状態です。このエラーは、サービスのメンテナンスや過負荷、またはサーバーレスサービスの起動遅延が主な原因です。 よくある原因 GCPサービスのメンテナンスまたは過負荷状態 Google Cloud全体またはあなたが利用しているサービス(Cloud Run、Cloud Functions、Cloud SQL等)がメンテナンス中または過負荷状態に陥っている場合に503エラーが発生します。これはGCP側の問題であり、ユーザーのアプリケーションコードには原因がありません。 Cloud Runのコールドスタート時のタイムアウト Cloud Runでは、デプロイ直後またはしばらくリクエストがない状態から新しいリクエストが来た場合、インスタンスの起動に時間がかかります。この起動中(コールドスタート)にリクエストがタイムアウトすると、503エラーが返されます。デフォルト設定では最小インスタンス数が0に設定されているため、起動待ちの間にリクエストが失敗しやすくなります。 リージョンの容量不足 特定のGCPリージョンで一時的に容量が足りなくなり、新しいインスタンスやリソースを作成できない状態に陥ることがあります。この場合も503エラーが返されます。 解決手順 ステップ1:GCPサービスの状態を確認する まず、GCP側で障害が発生していないか確認します。status.cloud.google.comにアクセスしてください。 # または curl コマンドでサービス状態ページを確認 curl https://status.cloud.google.com ページ上で「Service Status」から各サービスの状態を確認します。赤色やオレンジ色の警告が表示されている場合は、GCP側の問題です。この場合は復旧を待つしかありません。 ステップ2:Cloud Runの場合は min-instances を設定する Cloud Runを使用している場合、最小インスタンス数をを1以上に設定してコールドスタートを根絶します。 gcloud run deploy <your-service-name> \ --min-instances=1 \ --region=<your-region> \ --project=<your-project-id> 既存サービスの設定を変更する場合は以下を実行します。 gcloud run services update <your-service-name> \ --min-instances=1 \ --region=<your-region> \ --project=<your-project-id> Cloud Consoleから設定する場合は、Cloud Run → サービス一覧 → 対象サービスをクリック → 「編集して新しいリビジョンをデプロイ」 → 「詳細設定」→「最小インスタンス数」を1に変更します。 ステップ3:数分待機してから再試行する GCP側の過負荷状態である場合、通常は数分~数十分で復旧します。指数バックオフ(最初は短い待機時間、失敗するたびに待機時間を増やす)を実装して自動再試行します。 import requests import time def fetch_with_retry(url, max_retries=5): for attempt in range(max_retries): try: response = requests.get(url, timeout=10) response.raise_for_status() return response except requests.exceptions.HTTPError as e: if e.response.status_code == 503: wait_time = 2 ** attempt # 1秒、2秒、4秒、8秒、16秒... print(f"503エラー発生。{wait_time}秒後に再試行します...") time.sleep(wait_time) else: raise raise Exception("最大リトライ回数に達しました") ステップ4:ログを確認してアプリケーションの問題がないか確認する ...
OpenAI API の 409 エラー:原因と解決策409
OpenAI API で 409 エラーが返される場合、リクエストの内容がサーバー上のリソースの現在の状態と競合しています。通常、既に進行中の操作や重複したリソースが原因となります。 よくある原因 Fine-tuningジョブの重複実行 同じトレーニングデータやモデルに対して、既に実行中のFine-tuningジョブがあるのに、さらに同じ設定で新しいジョブを作成しようとするとこのエラーが発生します。OpenAI API はアカウント内で同時に実行できるFine-tuningジョブの数に制限があり、また同一のトレーニングデータセットに対して並行実行できないためです。 ファイルのアップロード競合 Files API を使用してトレーニングファイルをアップロードする際に、既にアップロード中や処理中のファイルIDに対して再度アップロードリクエストを送信すると競合が発生します。同じファイルIDに複数のアップロード操作が並行実行されようとするとき、この409エラーが返されます。 モデルカスタマイズの状態競合 Fine-tuning済みモデルに対して、訓練完了前にさらに別のFine-tuningジョブを開始しようとした場合、リソースの状態競合として扱われることがあります。 解決手順 ステップ1:実行中のFine-tuningジョブを確認する まず現在実行中のジョブを一覧表示して、重複するジョブがないか確認します。 # 実行中のFine-tuningジョブを一覧表示 curl https://api.openai.com/v1/fine_tuning/jobs \ -H "Authorization: Bearer $OPENAI_API_KEY" レスポンスを確認して、対象のトレーニングデータと同じ設定のジョブが既に running または queued 状態で存在していないか確認します。 ステップ2:完了済みジョブの確認とクリーンアップ 既に完了したジョブが大量に残っていないか確認し、必要に応じて確認します。 # 特定のジョブの詳細情報を確認 curl https://api.openai.com/v1/fine_tuning/jobs/<job-id> \ -H "Authorization: Bearer $OPENAI_API_KEY" ステータスが succeeded や failed であれば、新しいジョブは作成できます。running の場合は完了まで待機する必要があります。 ステップ3:ファイルのアップロード状態を確認する Files API でアップロード済みファイルの状態を確認します。 # アップロード済みファイル一覧を取得 curl https://api.openai.com/v1/files \ -H "Authorization: Bearer $OPENAI_API_KEY" # 特定のファイル情報を確認 curl https://api.openai.com/v1/files/<file-id> \ -H "Authorization: Bearer $OPENAI_API_KEY" ファイルのステータスが processed になっていることを確認してから、Fine-tuningジョブを再度作成します。 ステップ4:新しいFine-tuningジョブを作成する 競合するジョブがないことを確認した後、新しいジョブを作成します。 ...
OpenAI API の 422 エラー:原因と解決策422
OpenAI APIで422エラーが発生するのは、リクエストの構文は正しいものの、含まれるデータが処理要件を満たしていないときです。特にFine-tuningでよく出現するエラーです。 よくある原因 Fine-tuningのJSONLファイル形式が不正 Fine-tuningに使用するJSONLファイルの各行が、OpenAIが定める正しい形式になっていない場合、422エラーが返されます。例えば、JSON形式で統一されていなかったり、不要なフィールドが含まれていたり、必須フィールドが欠けていたりすると、OpenAI側で処理できないと判断されるためです。 messagesフォーマットが要件と異なる Fine-tuningのデータセットでは、各サンプルがmessages配列を含む必要があります。その配列内のメッセージオブジェクトがroleとcontentフィールドを持っていなかったり、roleの値が不正な値(例:「user_message」など)だったりすると、422エラーが返されます。OpenAIは厳密なスキーマ検証を行うため、わずかな形式のズレでも拒否されるのです。 データセット件数が最小要件を下回っている Fine-tuningには最低限のサンプル数(通常は10件以上、推奨は50件以上)が必要です。これを満たさないデータセットをアップロードしようとすると、422エラーで拒否されます。 JSONLファイルに無効なJSON行が含まれている 各行が有効なJSON形式になっていない場合、422エラーが返されます。例えば、シングルクォートの使用、末尾のカンマ、エスケープ漏れなども原因になります。 解決手順 1. JSONLファイルの形式を確認する Fine-tuningデータは、1行1個の有効なJSONオブジェクトからなるJSONL形式である必要があります。以下が正しいサンプルです。 {"messages": [{"role": "system", "content": "あなたは優秀なアシスタントです。"}, {"role": "user", "content": "こんにちは"}, {"role": "assistant", "content": "こんにちは。何かお手伝いできることはありますか?"}]} {"messages": [{"role": "system", "content": "あなたは優秀なアシスタントです。"}, {"role": "user", "content": "天気は?"}, {"role": "assistant", "content": "申し訳ございませんが、リアルタイムの天気情報は提供できません。"}]} ファイルの各行が独立した有効なJSONであることをテキストエディタで目視確認します。 2. Pythonでファイルの検証を行う 以下のスクリプトで、JSONL形式とmessagesの構造を自動検証します。 import json def validate_jsonl(file_path): with open(file_path, 'r', encoding='utf-8') as f: for line_num, line in enumerate(f, start=1): try: data = json.loads(line) # messagesフィールドが存在するか確認 if 'messages' not in data: print(f"行 {line_num}: 'messages' フィールドが見つかりません") continue # messagesは配列か確認 if not isinstance(data['messages'], list): print(f"行 {line_num}: 'messages' が配列ではありません") continue # 各メッセージが role と content を持つか確認 for msg_num, msg in enumerate(data['messages']): if 'role' not in msg or 'content' not in msg: print(f"行 {line_num}、メッセージ {msg_num}: 'role' または 'content' が見つかりません") if msg.get('role') not in ['system', 'user', 'assistant']: print(f"行 {line_num}、メッセージ {msg_num}: roleが不正です(値:{msg.get('role')})") except json.JSONDecodeError as e: print(f"行 {line_num}: JSON形式エラー - {e}") print("検証完了") validate_jsonl('<your-file-path>.jsonl') 3. データセット件数を確認する ...
Podman の 400 エラー:原因と解決策400
Podman実行時に「400 Bad Request」が出ています。このエラーはPodman APIまたはレジストリへのリクエスト形式が正しくないことを示しており、コマンドオプションやイメージ指定の誤りが原因です。 よくある原因 podman runコマンドのオプション指定が誤っている podman run のオプション順序やフラグの書き方が間違っていると、Podmanはリクエストを解析できず400エラーを返します。例えば、値が必要なオプション(--name、--memory など)に値を渡さない、または重複定義した場合に発生します。イメージ指定の前に全てのオプションを配置する必要があります。 イメージ名またはタグの書き方が間違っている イメージ名やタグの形式が不正だとリクエストが成立しません。レジストリが指定されていない場合、Podmanはデフォルトレジストリから検索しますが、タグ内に無効な文字が含まれていたり、参照形式が壊れていたりするとエラーになります。 Podman APIソケットへのリクエストのJSON形式が壊れている REST APIを直接呼び出す場合、JSONペイロードの構文エラーや必須フィールドの不足があると400エラーが発生します。curlなどでAPIを叩く際にダブルクォートの閉じ忘れやカンマの欠落が原因になります。 解決手順 ステップ1:コマンドオプションの正しい書き方を確認する # 使用しているサブコマンドのヘルプを表示 podman help run # よく使うオプション例 podman run --name <コンテナ名> --memory 512m --cpus 1 <イメージ名>:<タグ> podman help run でオプション一覧と説明を確認し、オプション順序やフラグの記述が正しいか検証します。イメージ指定は必ずオプション指定の後に配置してください。 ステップ2:イメージ名とタグをpodman searchで検証する # イメージ検索でレジストリに存在するか確認 podman search alpine # タグ付きで正確なイメージ名を指定 podman run alpine:3.18 /bin/sh # レジストリを明示的に指定する場合 podman run docker.io/library/alpine:3.18 /bin/sh podman search で目的のイメージがレジストリに存在し、正確なタグ名を確認します。タグが存在しない、または大文字小文字が異なっている場合も400エラーになります。 ステップ3:Podmanをバージョン確認し、必要に応じて更新する # 現在のPodmanバージョンを確認 podman --version # 古い場合はシステムパッケージマネージャーで更新 # Red Hat系の場合 sudo dnf update podman # Debian系の場合 sudo apt update && sudo apt upgrade podman 古いバージョンではAPI仕様が異なり、新しいオプションが存在しないか動作が異なる可能性があります。 ...
Podman の 401 エラー:原因と解決策401
Podmanでコンテナイメージをpullやpushしようとすると、401認証エラーが発生することがあります。このエラーはレジストリへの認証に失敗したときに出現し、適切な認証情報がないか有効期限切れの状態を示しています。 よくある原因 podman loginを実行していない Podmanでレジストリからイメージを取得するには、事前に認証を完了する必要があります。ログイン処理を行わずにpullコマンドを実行すると、認証情報がないため401エラーが発生します。特に新しい環境構築時や、別のレジストリを利用する場合に見落とされやすいです。 認証トークンの有効期限が切れている レジストリが発行した認証トークンには有効期限が設定されていることが多いです。数週間から数ヶ月経過すると、以前ログインした認証情報が無効化されてしまい、401エラーが返されます。 ~/.config/containers/auth.jsonの認証情報が古い Podmanはログイン時の認証情報を ~/.config/containers/auth.json に保存します。このファイルの内容が古い、破損している、または複数のレジストリ情報が混在していると、401エラーが発生することがあります。 解決手順 ステップ1:現在のログイン状態を確認する まず、どのレジストリに対して認証情報が保存されているか確認します。 # auth.jsonの内容を確認 cat ~/.config/containers/auth.json ファイルが存在しない場合や、対象のレジストリURLが記載されていなければ、ログインが必要です。 ステップ2:対象のレジストリに再ログインする 次のコマンドでレジストリに対してpodman loginを実行します。レジストリURLは正確に指定してください。 # Docker Hubの場合 podman login docker.io # プライベートレジストリの場合(例:プライベートGCR) podman login gcr.io # ユーザー名とパスワードを聞かれるので入力する # Username: <your-username> # Password: <your-password> ログインが成功すると、認証情報が ~/.config/containers/auth.json に保存されます。 ステップ3:auth.jsonを削除して再ログインする 上記ステップで解決しない場合、auth.jsonを完全に削除した上で再度ログインしてください。この方法で古い認証情報をクリアできます。 # auth.jsonを削除 rm ~/.config/containers/auth.json # 再度ログイン処理を実行 podman login <レジストリURL> 削除後、新しい認証情報が~/.config/containers/auth.jsonに保存されます。 ステップ4:レジストリURLが正しく指定されているか確認する pullやpushコマンドを実行する際、指定しているレジストリURLが正確か確認します。レジストリURLが異なると、別のレジストリとして認識され、認証エラーが発生します。 # 正しいレジストリURLでpullを実行 podman pull docker.io/library/ubuntu:latest # pullが成功することを確認 podman images ログイン後にpullコマンドを再度実行して、401エラーが解消されたか確認します。 ...