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 に続くアドレスとポートが、台帳で衝突した相手を示します。 ...

2026年8月3日 · ErrorLog

Docker の context deadline exceeded エラー:原因と解決策

冒頭まとめ context deadline exceeded は、Docker が独自に定義したエラーではありません。Docker が書かれている Go 言語の標準の仕組みが返す、時間切れを表すエラーです。Go のソースでは、この文字列を返す値が定義されており、時間切れかどうかを尋ねると真を返すことも明記されています。つまりこの文言が伝えているのは「何かの締め切りに間に合わなかった」という事実だけで、どこの締め切りかは書かれていません。だからこそ、締め切りの持ち主を特定しないまま設定をいじると、直らないまま時間だけが過ぎます。 特定の手がかりは、文言の末尾です。3通りあります。 括弧が何も付かず context deadline exceeded だけの場合、切れたのは呼び出し側が設定した締め切りです。末尾に (Client.Timeout exceeded while awaiting headers) が付く場合、クライアント自身の制限時間が、応答の見出し部分が届く前に切れています。末尾が (Client.Timeout or context cancellation while reading body) の場合、見出しは届いており、本体の転送の途中で切れています。この2つの接尾辞は、Go の HTTP の実装の中でそれぞれ別の場所に定義されており、付く条件も違います。前者なら接続・名前解決・プロキシ・相手の無応答を、後者なら転送速度と転送量を疑う、という具合に、見るべき場所が変わります。 もう1つ、先に否定しておくべき助言があります。「COMPOSE_HTTP_TIMEOUT を大きくする」という案内が今も多く見つかりますが、Docker Compose の公式文書には「Compose V2 では効果がない環境変数」という一覧があり、この環境変数はそこに挙げられています。設定しても何も変わりません。 境界も引いておきます。context canceled は時間切れではなく取り消しで、別のエラーです。Go のソースでも別の値として定義されています。 エラーの概要 実際に見かける形を並べます。まずイメージの取得で出るもの。 Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline exceeded (Client.Timeout exceeded while awaiting headers) 次にビルドで出るもの。 failed to solve: example:1.0: failed to resolve source metadata: context deadline exceeded そして転送の途中で切れたもの。進捗が途中まで進んでから止まるのが特徴です。 ...

2026年7月28日 · ErrorLog

Docker の invalid reference format エラー:原因と解決策

冒頭まとめ invalid reference format は、イメージの指定が文法に合っていない、という判定です。重要なのは、この判定がレジストリへ問い合わせる前に手元で行われることです。通信は一切発生していないので、存在しないイメージを指したときの応答(404)とは別の段階の話になります。認証や通信経路を疑っても意味がありません。 文言は2種類あり、意味がはっきり違います。invalid reference format だけの場合と、invalid reference format: repository name must be lowercase と続く場合です。この2つは、Docker がイメージ名を解析する部分のソースで、明確に別の値として定義されています。解析の流れは、まず文字列を文法と照合し、合わなければ全体を小文字にしてもう一度照合する、という順です。小文字にすれば通る場合だけ「小文字でなければならない」という文言を返し、それ以外はすべて一般の文言になります。 この違いは、原因を絞るのにそのまま使えます。小文字を求める文言が出たということは、Docker が受け取った文字列は「大文字さえ無ければイメージ名として成立していた」ということです。イメージ名を大文字で書いた覚えがないのにこれが出るなら、渡ってしまったのは大文字を含む別の何か、たとえばファイルのパスである可能性が高くなります。 そして、実務で最も多い原因はイメージ名そのものではありません。シェルが Docker に渡した文字列が、書いたつもりのものと違っているという形です。したがって最初にやるべきは、名前を直すことではなく、実際に何が渡ったかを確かめることです。 エラーの概要 実行時の出力はこの形です。 docker: invalid reference format. See 'docker run --help'. 小文字を求める場合はこうなります。 docker: invalid reference format: repository name must be lowercase. See 'docker run --help'. 解析部分のソースには、この判定に関わるエラーが5つ定義されています。文法に合わない場合、小文字でない場合、名前が空の場合、名前が長すぎる場合、タグの書式が不正な場合です。名前の長さの上限は255文字と定義されています。 文法そのものも定義を読むと明快です。名前の各部分は小文字の英数字で始まり、区切りとして点1つ、下線1つか2つ、連続する横棒が使えます。それらを斜線でつないだものが名前です。一方、タグは英数字か下線で始まり、以降に点と横棒を含められ、全体で128文字までです。つまりタグには大文字を使えます。 この非対称は覚えておく価値があります。myapp:V1.0 は通り、MyApp:v1.0 は通りません。名前は小文字だけ、タグは大文字も可、という組み合わせです。 もう1つ、レジストリの指定にも規則があります。名前の先頭部分がレジストリとして扱われるのは、点を含むか、コロンとポート番号が付く場合、そして localhost の場合だけです。定義にもそう書かれています。点もポートも含まない語は、レジストリではなく名前の一部として扱われます。 まず最初に:渡った文字列を確認する 第一に、文言のどちらが出ているかを見ます。小文字を求める文言なら、渡った文字列は大文字を含む何かです。一般の文言なら、小文字にしても通らない文字列です。 第二に、実際に渡った引数を表示させます。シェルの展開を経た後の姿を見るのが目的です。 set -x docker run --rm -v "$(pwd)":/app "$IMAGE:$TAG" set +x 第三に、空の変数を疑います。名前かタグのどちらかが空になると、このエラーになります。次の3つはいずれも同じ結果です。 docker run :latest docker run debian: docker run : 第四に、コマンドを1行に書き直して実行してみます。行の折り返しに使う記号のうしろに余計な空白が入っていると、そこで行が終わったことにならず、想定外の引数が生まれます。この形は目視で見つけにくいので、1行にまとめると再現しなくなることで気付けます。 ...

2026年7月28日 · ErrorLog

Docker Compose の .env 読み込みエラー:UTF-16 BOM問題と解決策

Windows環境でDocker Composeを使う際、PowerShellで作成した.envファイルが原因でコンテナが起動できないケースがあります。エラーメッセージに\xff\xfeやunexpected characterが含まれている場合、ファイルのエンコードが原因です。 エラーの全文 failed to read C:\Users\user\project\.env: line 1: unexpected character "?" in variable name "\xff\xfeG\x00O\x00O\x00G\x00L\x00E\x00_\x00A\x00P\x00I\x00_\x00K\x00E\x00Y\x00=\x00A\x00I\x00z\x00a\x00..." \xff\xfe はUTF-16 LEのBOM(Byte Order Mark)です。続く\x00が各文字の後ろに並んでいることから、ファイル全体がUTF-16 LEで保存されていることがわかります。Docker ComposeのenvファイルパーサーはUTF-8(BOMなし)のみを受け付けるため、このファイルを読み込もうとした瞬間にクラッシュします。 よくある原因 PowerShellのechoコマンドはUTF-16 LEで書き出す WindowsのPowerShell(5.1系)では、リダイレクト演算子>やechoコマンドがデフォルトでUTF-16 LE(BOM付き)を使用します。 # これをやってはいけない echo GOOGLE_API_KEY=AIzaSy... > .env # → .envがUTF-16 LE(BOM付き)で保存される Linuxや macOSのシェルと違い、PowerShellは歴史的な経緯からUTF-16をデフォルトエンコードとして採用しています。echoやSet-Contentを使う限り、意識しない限りこの問題が発生します。 VSCodeのエンコード設定が変わっている場合 VSCodeでファイルを新規作成・保存する際、右下のステータスバーが「UTF-16 LE」になっているとDocker Composeが読めないファイルが生成されます。 診断方法 .envファイルの先頭バイトを確認します。 # 先頭4バイトを16進数で確認 $bytes = [System.IO.File]::ReadAllBytes(".env") $bytes[0..3] | ForEach-Object { $_.ToString("X2") } 正常(UTF-8 BOMなし): 47 4F 4F 47 ← "GOOG"の文字コード(例:GOOGLE_API_KEY=...) 異常(UTF-16 LE BOM付き): FF FE 47 00 ← \xff\xfe がBOM、その後\x00が混入 解決手順 方法1:既存の.envファイルをUTF-8に変換する(即時対応) # UTF-16で書かれた.envをUTF-8(BOMなし)に変換して上書き $content = Get-Content ".env" -Encoding Unicode -Raw [System.IO.File]::WriteAllText( (Resolve-Path ".env").Path, $content.Trim() + "`n", [System.Text.UTF8Encoding]::new($false) ) $falseは「BOMを付けない」を意味します。UTF8Encoding::new($true)にするとBOM付きになるため注意してください。 ...

2026年5月30日 · ErrorLog

Docker の 400 エラー:原因と解決策

冒頭まとめ Docker の 400 Bad Request は、デーモンまで届いたリクエストの形式や値が不正で、デーモンが処理を始められなかったことを示します。実際の環境で最も多いのは、クライアントとデーモンの API バージョン不一致です。エラー文言が client version <番号> is too new(クライアントが新しすぎる)または too old(古すぎる)なら、これに該当します。新しい CLI やツールと古いデーモンの組み合わせ、CI の Docker-in-Docker 構成、DOCKER_API_VERSION 環境変数の固定ミスが典型です。そのほか、デーモンの API を直接呼び出す場合の壊れた JSON や、設定値の検証で弾かれるケースが400になります。 逆に、400と誤解されやすいが400ではないものも押さえておくと迷いません。Dockerfile の構文エラーはビルド時の解析エラー、compose ファイルの YAML 不正はクライアント側の読み込みエラー、イメージ名の形式違反は invalid reference format としてデーモンに送る前に拒否されます。いずれもデーモンの400応答ではなく、調査の場所が異なります。 エラーの概要 docker コマンドは、裏側で Docker デーモンの API に HTTP リクエストを送るクライアントです。Error response from daemon: で始まるエラーは、リクエストがデーモンまで届いたことを意味します。デーモンは、不正なパラメータに分類されるエラーを 400 として応答する実装になっており(Docker のソースコードで確認できます)、API バージョンの範囲外もこの分類に含まれます。実際の報告に共通する文言は次の2種です。 Error response from daemon: client version 1.52 is too new. Maximum supported API version is 1.43 Error response from daemon: client version 1.41 is too old. Minimum supported API version is 1.44 too new はクライアントの要求する API バージョンがデーモンの上限を超えている状態、too old は逆に、デーモンが受け付ける下限より古い状態です。後者は、Docker Engine のバージョン29が受け付ける最小 API バージョンを引き上げたことに伴い、古いクライアントやツールを使う環境で報告が増えています。 ...

2026年1月1日 · ErrorLog

Docker の 401 エラー:原因と解決策

エラーの概要 Dockerで401エラーが発生するのは、レジストリ(Docker Hub、ECR、プライベートレジストリなど)への認証に失敗したときです。認証情報が提供されていない、または提供されていても無効・期限切れの場合に表示されます。特に docker pull、docker push、docker login の実行時によく見られます。 なお、2020年11月以降、Docker Hubの匿名(ログインなし)でのイメージダウンロード数に制限が導入されたため、以前はログインなしで利用できていたパブリックイメージでも、現在は認証が必須になるケースが増えています。 実際のエラーメッセージ例 Error response from daemon: unauthorized: incorrect username or password { "errors": [ { "code": "UNAUTHORIZED", "message": "authentication required", "detail": null } ] } Error response from daemon: Get "https://registry-1.docker.io/v2/": unauthorized: authentication required, 401 よくある原因と解決手順 原因1:Docker Hubへのログインが完了していない Docker Hubのパブリックイメージであっても、ダウンロード数制限により認証が必須になるケースがあります。また、プライベートイメージにアクセスする場合は必ず認証が必要です。 Before(エラーが起きるコード): # ログインなしで直接pullを実行 docker pull <your-username>/<image-name>:latest After(修正後): # 最初にDocker Hubにログイン docker login # プロンプトにユーザー名とパスワード(またはPersonal Access Token)を入力 # その後でpullを実行 docker pull <your-username>/<image-name>:latest 原因2:AWS ECRの認証トークンが期限切れ ECRの認証トークンは12時間の有効期限があります。Docker daemonに保存されたトークンが期限切れになると401エラーが発生します。 ...

2026年1月1日 · ErrorLog

Docker の 403 エラー:原因と解決策

エラーの概要 Docker の 403 エラーは、認証(ログイン)には成功したものの、対象のリソース(イメージ、レジストリ、ボリューム等)へのアクセス権限がないことを示します。これはプライベートリポジトリへのアクセス、組織内のアクセス制限、または不十分な認証トークンの権限が原因で発生することがほとんどです。Docker CLI、Docker Desktop、または docker push/pull 時に頻繁に遭遇するエラーです。 実際のエラーメッセージ例 Error response from daemon: Head "https://registry-1.docker.io/v2/myuser/myimage/manifests/latest": unauthorized: authentication required 403 Forbidden { "errors": [ { "code": "DENIED", "message": "permission denied", "detail": "requested access to the resource is denied" } ] } docker push myrepo/myimage:tag denied: requested access to the resource is denied よくある原因と解決手順 原因1:Docker Hub のログイン認証が無効または権限不足 なぜ発生するか:Docker CLI がログインしていない状態、または無効なトークンでリポジトリにアクセスしようとすると、403 エラーが返されます。特にプライベートリポジトリの場合、認証なしでのアクセスが拒否されます。 Before(エラーが起きるコマンド) # ログインせずにプライベートリポジトリをプルしようとする docker pull myusername/private-image:latest # または古い認証情報で実行 docker push myrepo/myimage:tag After(修正後のコマンド) ...

2026年1月1日 · ErrorLog

Docker の 404 エラー:原因と解決策

冒頭まとめ Docker の 404 は「指定したものが見つからない」ことを示しますが、探した場所によって原因も対処も変わります。系統は3つです。第一に、手元のデーモンが管理する資源が見つからない場合で、No such container: や No such image: という文言になります。第二に、レジストリ(Docker Hub などのイメージ保管先)にリポジトリはあるがタグが見つからない場合で、manifest for … not found という文言になります。第三に、リポジトリ自体にたどり着けない場合で、pull access denied for …, repository does not exist or may require ‘docker login’ という文言になります。この3つ目の文言が「存在しない」と「権限がない」を並記しているのは意図的な設計で、Docker Hub は非公開リポジトリの存在を外部に確認させないため、両者を区別しないエラーを返します。 つまり Docker の404の調査は、エラー文言を読んで「手元」「タグ」「リポジトリ(または権限)」のどれかを確定するところから始まります。 エラーの概要 docker コマンドのエラーで Error response from daemon: と付くものは、Docker デーモンまで指示が届いたうえで、デーモンが処理を拒否したことを示します。デーモンは、コンテナやイメージなどの資源が見つからない場合、API 上は 404 として応答し、CLI には No such container: <名前> のような文言で表示されます(この対応は Docker のソースコードで確認できます)。一方、docker pull や docker push でレジストリとやり取りする場合の404は、レジストリ側の応答に由来します。レジストリの標準仕様では、リポジトリ名が不明な場合のエラーコードは NAME_UNKNOWN(repository name not known to registry)で、これも HTTP 404 に対応付けられています。 どの場合も、エラーコードの数字より文言のほうが多くを語ります。以下、文言ごとに切り分けます。 まず最初に:エラー文言で3つに分岐する No such container: <名前> や No such image: <名前> なら、手元のデーモンの中に該当する資源がありません(原因1)。 ...

2026年1月1日 · ErrorLog

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

エラーの概要 Dockerの409エラーは、HTTP標準仕様で「Conflict」を示すステータスコードです。Docker Daemonがコンテナやイメージの操作を受け付けられない状態を表します。通常、リソースの重複、ポートの競合、不正なコンテナの状態遷移などが原因となります。このエラーが発生した場合、現在のシステム状態と実行しようとしている操作に矛盾があることを意味しており、Dockerコマンド実行時やAPI呼び出し時に頻繁に遭遇します。 実際のエラーメッセージ例 { "message": "Error response from daemon: Conflict. The container name \"/web-app\" is already in use by container \"abc123def456\". You have to remove (or rename) that container to be able to reuse that name." } $ docker run --name myapp nginx docker: Error response from daemon: Conflict. The container name "/myapp" is already in use by container "e7f8c9a2b1d4". You have to remove (or rename) that container to be able to reuse that name. よくある原因と解決手順 原因1:コンテナ名の重複 同じ名前のコンテナが既に存在する場合、新たに同じ名前でコンテナを作成しようとすると409エラーが発生します。停止中のコンテナであっても名前は保持されるため、docker run --name で既存の名前を指定するとエラーになります。 ...

2026年1月1日 · ErrorLog

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

エラーの概要 Dockerで 422 エラーが発生するのは、Docker APIまたはコンテナレジストリへのリクエストが構文的には正しいものの、含まれるデータが処理要件を満たしていない場合です。Docker Daemon、Docker Compose、レジストリ APIとの通信時にこのエラーが返される典型的なシナリオは、不正なイメージタグ指定、設定値の型違反、あるいは APIスキーマの検証失敗です。 実際のエラーメッセージ例 { "message": "invalid tag format", "code": 422 } $ docker push myregistry.example.com/app:invalid@tag Error response from daemon: invalid tag format # docker-compose.yml でエラーが発生 ERROR: The Compose file is invalid because: Service 'web' has invalid value for ports: ports must be an integer or string よくある原因と解決手順 1. イメージタグの形式が不正 Dockerレジストリ APIは RFC 6391 に基づいたタグ形式を要求します。許可されない文字(@や大文字の混在)が含まれている場合に 422 が返されます。 Before(エラーが起きる例): docker tag myimage:latest myregistry.example.com/app:INVALID@latest docker push myregistry.example.com/app:INVALID@latest # Error: invalid tag format After(修正後): # タグは小文字のみで、「:」で区切る docker tag myimage:latest myregistry.example.com/app:v1.0.0 docker push myregistry.example.com/app:v1.0.0 2. docker-compose.yml の設定値の型違反 ports、mem_limit、cpu_sharesなど、数値型を期待するフィールドに文字列を指定するとバリデーション失敗で 422 が返されます。 ...

2026年1月1日 · ErrorLog