Docker port is already allocated

Docker の port is already allocated:原因と解決策

冒頭まとめ port is already allocated を見たとき、多くの人は「そのポートで何かが待ち受けている」と考えます。しかし実装を読むと、この文言を出しているのは Docker 自身の割り当て台帳です。 Docker は公開ポートを管理する専用の仕組みを持っており、アドレスとプロトコルごとの対応表を内部に保持しています。要求されたポートをこの台帳と照合し、既に登録されていれば「Bind for アドレス:ポート failed: port is already allocated」という文言のエラーを返します。この時点で、実際に接続を試みてはいません。 したがって、ss や lsof で調べて誰も待ち受けていなくても、このエラーは出ます。台帳と実態がずれている状態です。 一方、基本ソフトウェアの側が拒否した場合、文言は変わります。 Ports are not available: exposing port TCP 0.0.0.0:3000 -> 0.0.0.0:0: listen tcp 0.0.0.0:3000: bind: address already in use port is already allocated は Docker の台帳、address already in use は基本ソフトウェア。この2つを見分けることが、切り分けの出発点になります。 エラーの概要 台帳が断った場合の典型です。 docker: Error response from daemon: driver failed programming external connectivity on endpoint my-app (a1b2c3...): Bind for 0.0.0.0:8080 failed: port is already allocated. 前半の「外部接続の設定に失敗した」は経緯の説明で、読むべきは末尾です。Bind for に続くアドレスとポートが、台帳で衝突した相手を示します。 ...

Ports are not available: exposing port TCP 0.0.0.0:3000 -> 0.0.0.0:0:
  listen tcp 0.0.0.0:3000: bind: address already in use
2026年8月3日 · ErrorLog
AWS 504

ELB の 504 エラー:原因と解決策

冒頭まとめ ELB の 504 Gateway Timeout を調べるとき、最初にやるべきことは原因の推測ではありません。その 504 を、ロードバランサが作ったのか、ターゲットが返したのかを確定させることです。 この2つは、調べる場所がまったく違います。前者ならロードバランサとターゲットの間の話、後者ならターゲットの内側の話です。にもかかわらず、クライアントから見える応答は同じ 504 です。 判定は一瞬で終わります。アクセスログの target_status_code を見るだけです。公式文書によれば、この欄はターゲットへの接続が確立され、かつターゲットが応答を返した場合にのみ記録され、それ以外は - になります。つまり elb_status_code が 504 で target_status_code が - ならロードバランサ生成、両方 504 ならターゲット自身が返した 504 です。多段構成でターゲット側に別の中継役がいる場合、後者になります。 ロードバランサ生成だった場合、原因は公式に6つ挙げられています。関わるタイマーは2種類で、接続を確立するまでの10秒と、応答を待つ idle timeout(既定60秒)です。前者は変更できません。 なお、よく混同されますが、ターゲット側の keep-alive がロードバランサの idle timeout より短い場合に返るのは 504 ではなく 502 です。公式の 502 の説明にその条件が明記されています。 エラーの概要 アクセスログの1行から読み取れる情報が、このエラーの診断の中心です。 https 2026-08-03T12:00:00.000000Z app/my-alb/50dc6c495c0c9188 203.0.113.10:54321 10.0.1.23:8080 0.001 -1 -1 504 - 512 0 "GET https://example.com:443/report HTTP/1.1" 読むべき欄は3つです。 elb_status_code が 504。target_status_code が -。この2つが揃えば、ロードバランサが生成した 504 です。 ...

https 2026-08-03T12:00:00.000000Z app/my-alb/50dc6c495c0c9188 203.0.113.10:54321
  10.0.1.23:8080 0.001 -1 -1 504 - 512 0 "GET https://example.com:443/report HTTP/1.1"
2026年8月3日 · ErrorLog
GitHub Host key verification failed

GitHub の Host key verification failed:原因と解決策

冒頭まとめ Host key verification failed. を出しているのは GitHub ではありません。**手元の SSH クライアント**です。意味は「接続先が名乗っている身元を、こちらでは確認できなかった」ということです。 認証の失敗ではない点に注意してください。鍵が正しいかを問う以前の段階で、相手が本物の github.com かどうかを確かめています。 実装を読むと、この段階には2つの分岐があります。1つは記録に無い場合です。相手の鍵を初めて見たとき、対話できる環境なら「この接続先の真正性を確認できません」と表示して確認を求めます。対話できない環境では、確認のしようがないので失敗します。自動処理やコンテナの中でこのエラーが出るのは、ほぼこの形です。 もう1つは記録と違う場合です。この場合は大きな警告が出ます。実装では「接続先の識別情報が変わった」という囲み枠に加えて、記録の何行目が該当するかまで表示されます。 そして重要なのは、この警告は「攻撃かもしれない」と「正当な鍵の交換かもしれない」の両方を意味することです。どちらかを判断するのは利用者の側です。判断材料はあります。GitHub は接続先の鍵の指紋を文書として公開し、API からも配信しています。突き合わせれば、自分で判断できます。 エラーの概要 記録に無い場合、対話できる環境ではこう表示されます。 The authenticity of host 'github.com (140.82.x.x)' can't be established. ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU. Are you sure you want to continue connecting (yes/no/[fingerprint])? 対話できない環境では確認が省略され、そのまま次の文言で終わります。 Host key verification failed. fatal: Could not read from remote repository. 記録と違う場合は、囲み枠付きの警告になります。 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ... Add correct host key in /home/user/.ssh/known_hosts to get rid of this message. Offending RSA key in /home/user/.ssh/known_hosts:12 Host key verification failed. Offending の行に、記録ファイルの何行目が該当するかが書かれています。この番号があれば、消すべき行が特定できます。 ...

The authenticity of host 'github.com (140.82.x.x)' can't be established.
ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
2026年8月3日 · ErrorLog
Kubernetes 409

Kubernetes の 409 エラー:原因と解決策

冒頭まとめ Kubernetes の 409 Conflict は、1つの意味を持つエラーではありません。実装を読むと、409 を返す構築関数が3つあります。 1つ目は、同じ名前のものが既に存在する場合です。区分は AlreadyExists、文言は対象の名前に「already exists」を付けた形になります。 2つ目は、更新しようとした対象が、読み取ってから書き込むまでの間に他者に変更されていた場合です。区分は Conflict、文言は「Operation cannot be fulfilled on …」で始まり、中に「the object has been modified; please apply your changes to the latest version and try again」が入ります。 3つ目は、Server-Side Apply でフィールドの所有権が衝突した場合です。区分は同じ Conflict ですが、details.causes にフィールドごとの衝突と、その所有者の名前が入ります。文言は「Apply failed with N conflict(s)」の形です。 この3つは、対処が正反対です。1つ目は既存を使うか名前を変える。2つ目は読み直してからやり直す。3つ目は所有権を奪うか、手放すか、共有するかを選ぶ。同じ要求をそのまま送り直して直るものは、1つもありません。 したがって、409 を見たら最初にやるのは reason の確認、次に details の確認です。kubectl は区分を括弧付きで表示するので、Error from server (AlreadyExists) か Error from server (Conflict) かがそのまま手がかりになります。 エラーの概要 既に存在する場合の応答です。 { "kind": "Status", "status": "Failure", "message": "configmaps \"app-config\" already exists", "reason": "AlreadyExists", "details": { "kind": "configmaps", "name": "app-config" }, "code": 409 } 楽観ロックの競合は、区分も文言も変わります。 ...

{
  "kind": "Status",
  "status": "Failure",
2026年8月3日 · ErrorLog
Kubernetes 422

Kubernetes の 422 エラー:原因と解決策

冒頭まとめ Kubernetes の 422 Unprocessable Entity は、区分が Invalid のエラーです。意味は明快で、内容は読めたが、検証を通らなかったという状態を指します。 このエラーの扱いやすさは、応答の details.causes にあります。実装を読むと、検証のエラー一覧がそのまま causes に変換され、各要素に どのフィールドか(field) と なぜ駄目か(reason) が入ります。reason に入る値は決まっていて、必須項目の欠落なら FieldValueRequired、値が不正なら FieldValueInvalid、対応していない値なら FieldValueNotSupported、禁止された操作なら FieldValueForbidden といった具合です。つまり、推測は不要です。どこがなぜ駄目かは応答に書かれています。 もう1つ、実務で最も誤解されている点があります。知らないフィールドを書いても 422 にはなりません。公式文書には、検証の水準を厳格にした場合、未知または重複したフィールドを検出すると 400 Bad Request で拒否する、と明記されています。さらに但し書きとして、既知のフィールドに型の違う値を入れた場合も 400 になる、とも書かれています。 したがって境界はこうなります。読めなかったのが 400、読めたが内容が通らなかったのが 422。綴りを間違えた、型を間違えた、というよくある失敗は 400 側に落ちます。422 が返っているなら、書式の問題ではなく意味の問題です。 エラーの概要 応答の構造は次の形です。details.causes が本体で、message はその要約にすぎません。 { "kind": "Status", "status": "Failure", "message": "Deployment.apps \"web\" is invalid: spec.selector: Invalid value: ...: field is immutable", "reason": "Invalid", "details": { "group": "apps", "kind": "Deployment", "name": "web", "causes": [ { "reason": "FieldValueInvalid", "field": "spec.selector", "message": "Invalid value: ...: field is immutable" } ] }, "code": 422 } kubectl からの見え方には特徴があります。実装を読むと、区分が Invalid の場合だけ専用の整形が行われ、他のエラーのような Error from server (...) の形にはなりません。 ...

{
  "kind": "Status",
  "status": "Failure",
2026年8月3日 · ErrorLog
Kubernetes 429

Kubernetes の 429 エラー:原因と解決策

冒頭まとめ Kubernetes の 429 Too Many Requests には、出どころの違う3つの系統があります。 1つ目は、API サーバーの過負荷保護です。優先度と公平性の仕組み(API Priority and Fairness)が、混雑時に要求を落とします。2つ目は、Pod の退避が PodDisruptionBudget に阻まれた場合です。これは過負荷とは無関係で、「今は許可できない」という意味の拒否です。3つ目は、API サーバー以外、たとえばイメージの取得元が返す制限です。 さらに厄介なのが、429 に見えて 429 ではないものです。ログに「client-side throttling, not priority and fairness」と出ている場合、要求はサーバーにまだ送られていません。クライアント側が自分で待っているだけです。この文言は、ソフトウェア側の実装で「優先度と公平性の仕組みではない」と明示的に書かれています。ここを取り違えると、サーバー側をいくら調べても何も出てきません。 したがって、429 に当たったら最初にやるのは原因の推測ではなく、どこが返したのかの確定です。応答の区分、details の内容、Retry-After の値、この3つで系統が決まります。 エラーの概要 過負荷保護による 429 は、素っ気ない応答です。優先度と公平性の仕組みが要求を落とすとき、実装は Retry-After ヘッダーを付けたうえで、本文に短い文言だけを返します。 HTTP/1.1 429 Too Many Requests Retry-After: 3 Too many requests, please try again later. 一方、退避が拒否された場合の応答は、構造化された情報を持ちます。 { "kind": "Status", "status": "Failure", "message": "Cannot evict pod as it would violate the pod's disruption budget.", "reason": "TooManyRequests", "details": { "causes": [ { "reason": "DisruptionBudget", "message": "The disruption budget web-pdb needs 7 healthy pods and has 6 currently" } ] }, "code": 429 } 同じ 429 でも、details.causes の有無で系統が分かれます。DisruptionBudget が入っていれば退避の拒否であり、混雑とは関係ありません。 ...

HTTP/1.1 429 Too Many Requests
Retry-After: 3
2026年8月3日 · ErrorLog
Kubernetes CreateContainerConfigError

Kubernetes の CreateContainerConfigError:原因と解決策

冒頭まとめ CreateContainerConfigError は、Kubernetes がコンテナを起動する前段階、設定を組み立てる段階で失敗したことを示します。イメージの取得は成功しており、コンテナの作成にも到達していません。 重要なのは、この文字列自体には原因が書かれていないことです。実装を見ると、これは分類のための名前で、kubectl get pods の状態欄にはこの名前だけが出ます。実際の原因は、kubectl describe pod のイベントの側に入ります。しかも、そのイベントの理由欄は CreateContainerConfigError ではなく Failed です。実装で理由の定数がそう定義されています。 原因の大半は、環境変数として参照している ConfigMap や Secret が解決できないことです。文言は2種類に分かれます。参照先そのものが無い場合は secret "app-secrets" not found の形、参照先はあるがキーが無い場合は couldn't find key API_KEY in Secret default/app-secrets の形になります。実装でも、この2つは別々の分岐で作られています。 もう1つ、実務で効く性質があります。kubelet は失敗しても作成を繰り返します。したがって、足りない ConfigMap や Secret を後から作れば、Pod を作り直さなくても起動します。実際の報告を見ても、イベントには同じ失敗が数分間で8回といった形で記録されています。 エラーの概要 まず状態欄です。分類名だけが出ます。 NAME READY STATUS RESTARTS AGE app-6f8d9c7b5-x4k2h 0/1 CreateContainerConfigError 0 64s 原因はイベントにあります。理由欄が Failed である点に注意してください。 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Pulled 3m (x8 over 9m) kubelet Successfully pulled image "app:v1.2" Warning Failed 3m (x8 over 9m) kubelet Error: secret "app-secrets" not found コンテナの状態を直接読むこともできます。分類名と文言が対で入っています。 ...

NAME                     READY   STATUS                       RESTARTS   AGE
app-6f8d9c7b5-x4k2h      0/1     CreateContainerConfigError   0          64s
2026年8月3日 · ErrorLog
Kubernetes Evicted

Kubernetes の Evicted:原因と解決策

冒頭まとめ Evicted は、Kubernetes の kubelet がノードの資源を守るために Pod を落とした状態です。実装では理由の文字列が Evicted と定義され、Pod は失敗として終了します。 最初に押さえるべきは、これは Pod が使いすぎたという意味ではないことです。公式文書によれば、kubelet は退避シグナルを閾値と比較して退避を決めます。判定の対象はノード側の空き資源です。既定のハード閾値は次のとおりです。 memory.available < 100Mi(Linux)/< 500Mi(Windows) nodefs.available < 10% imagefs.available < 15% nodefs.inodesFree < 5%(Linux) imagefs.inodesFree < 5%(Linux) つまり、ノードがこの線を割った瞬間に、誰かが落とされます。落とされる側の使用量の多さは、順番を決める材料にすぎません。 ここが最大の誤解の元です。文言には「Container X was using 122Ki, request is 0」のような使用量と要求量が並びますが、これは選ばれた理由であって、退避が起きた原因ではありません。この表現が分かりにくいという指摘は、公式の課題として複数回登録されています。 もう1つ、OOMKilled との違いも重要です。公式文書に明記があり、コンテナが OOM で落とされた場合は再起動方針に従って再起動されますが、Pod の退避では再起動されません。 エラーの概要 一覧では状態として現れます。 NAME READY STATUS RESTARTS AGE app-7d8f767544-pk4ch 0/1 Evicted 0 12m app-7d8f767544-q2n8x 0/1 Evicted 0 12m 詳細を見ると、フェーズは失敗、理由が Evicted、そして本文に経緯が入ります。 Status: Failed Reason: Evicted Message: The node was low on resource: ephemeral-storage. Threshold quantity: 94576558032, available: 92034400Ki. Container app was using 122Ki, request is 0, has larger consumption of ephemeral-storage. 実装を読むと、この文言は部品の組み合わせで作られています。どの資源が不足したか、閾値と実際の空き、そして選ばれたコンテナの使用量と要求量です。ほかに、ノードの状態を示す形式、一時領域の上限を超えた場合、一時的なボリュームの使用量が上限を超えた場合の文言も定義されています。 ...

memory.available   < 100Mi(Linux)/< 500Mi(Windows)
nodefs.available   < 10%
imagefs.available  < 15%
2026年8月3日 · ErrorLog
Kubernetes NodeNotReady

Kubernetes の NodeNotReady:原因と解決策

冒頭まとめ kubectl get nodes に NotReady と表示されたとき、まず確認すべきは条件の値です。Kubernetes の Ready 条件は3つの値を取り、表示は同じでも意味が違います。 公式の定義はこうです。True はノードが健全で Pod を受け入れられる状態、False は健全ではなく受け入れていない状態、そして Unknown はノード制御役が既定50秒の猶予の間にノードから連絡を受け取れなかった状態です。 この違いが調査の方向を決めます。False はノード自身が「準備できていない」と申告しているので、ノードの中を調べます。Unknown は申告そのものが届いていないので、ノードと制御側の間を調べます。ノードが正常に動いていても Unknown にはなり得ます。 時間の流れも押さえておくと役に立ちます。ノード制御役は5秒ごとに状態を確認し、連絡が途絶えて50秒で Unknown にします。そこから既定で5分待って、Pod の退去を始めます。この5分は、node.kubernetes.io/not-ready と node.kubernetes.io/unreachable に対して自動的に付与される猶予(tolerationSeconds=300)によるものです。 つまり、NotReady になってもすぐ Pod は動かない。逆に、5分を過ぎると一斉に動き始めます。 エラーの概要 一覧では状態として現れます。 NAME STATUS ROLES AGE VERSION node-01 Ready <none> 30d v1.32.1 node-02 NotReady <none> 30d v1.32.1 詳細を見ると、条件と最終連絡時刻が入ります。ここが判断材料です。 Conditions: Type Status LastHeartbeatTime Reason Message ---- ------ ----------------- ------ ------- MemoryPressure Unknown Mon, 03 Aug ... 12:01 NodeStatusUnknown Kubelet stopped posting node status. DiskPressure Unknown Mon, 03 Aug ... 12:01 NodeStatusUnknown Kubelet stopped posting node status. Ready Unknown Mon, 03 Aug ... 12:01 NodeStatusUnknown Kubelet stopped posting node status. すべての条件が同時に Unknown になっていれば、連絡が途絶えた形です。最終連絡時刻を見れば、いつ止まったかが分かります。 ...

NAME       STATUS     ROLES    AGE   VERSION
node-01    Ready      <none>   30d   v1.32.1
node-02    NotReady   <none>   30d   v1.32.1
2026年8月3日 · ErrorLog
Nginx 429

Nginx の 429 エラー:原因と解決策

冒頭まとめ Nginx で 429 Too Many Requests に出会ったとき、最初に押さえるべき事実があります。Nginx はレート制限の拒否に、既定で 429 を使いません。 公式文書を見ると、頻度を制限する仕組みの応答コードは limit_req_status で指定し、その既定値は 503 です。同時接続数を制限する仕組みも同様で、limit_conn_status の既定値はやはり 503 です。実装を読んでも、どちらも既定値として「サービス利用不可」を表す定数が設定されています。 つまり、Nginx が返した 429 には次のいずれかの理由があります。誰かが limit_req_status 429 または limit_conn_status 429 を明示的に設定した。上流のアプリケーションが返した 429 を、Nginx がそのまま中継している。あるいは、Nginx より前段の仕組みが返している。 逆方向の混乱もよく起きます。「429 を返すよう設定したのに 503 のままだ」という状況です。これは多くの場合、頻度の制限と接続数の制限が別々の設定であることを見落としているために起こります。片方だけ 429 にしても、もう片方が発動していれば 503 が返ります。 もう1つ、実務で効く事実があります。Nginx はレート制限で拒否するとき、待つべき時間を示すヘッダーを付けません。実装を確認しても、頻度と接続数のどちらの仕組みにも該当する記述はありません。429 に設定したとしても、クライアントは「いつ再試行してよいか」を知る手段がないままです。 エラーの概要 まず、既定の設定でレート制限に当たった場合の記録です。応答は 503 ですが、記録の文言は制限によるものだと分かる形になっています。 2026/08/03 12:00:00 [error] 1234#1234: *56 limiting requests, excess: 0.622 by zone "one", client: 203.0.113.10, server: example.com, request: "GET /search/ HTTP/1.1" limiting requests が頻度の制限、limiting connections が接続数の制限です。どのゾーンで拒否されたかも同じ行に出ます。この文言は応答コードを 429 に変えても変わりません。記録の文言と応答コードは独立している、と押さえてください。 ...

2026/08/03 12:00:00 [error] 1234#1234: *56 limiting requests,
  excess: 0.622 by zone "one", client: 203.0.113.10,
  server: example.com, request: "GET /search/ HTTP/1.1"
2026年8月3日 · ErrorLog