Claude Codeのcontainerd.sockエラーで全Bashが止まる原因と回避策
containerd入りのLinuxでBashツールが全コマンド失敗し、bwrapがcontainerd.sockのmkdirで止まる不具合。原因と設定で避けられない理由、回避策を並べます。
containerdが動いているLinuxホストでClaude Codeを起動すると、echo testのような単純なコマンドまで、次のエラーで毎回失敗することがあります。
bwrap: Can't mkdir parents for /run/containerd/containerd.sock: Permission deniedGitHub issue #93144がこの症状の報告で、openのままです。最大の特徴は、sandbox.enabledをfalseにしても、ツール呼び出しにdangerouslyDisableSandbox: trueを付けても直らないことです。ここでは症状の見分け方、報告された原因、設定では避けられない理由、報告者たちが試した回避策とその代償を順に見ます。
containerd.sockのmkdir失敗とは
#93144の報告者の環境は、Claude Code 2.1.266、Debian GNU/Linux 13(trixie)、x86_64です。ユーザーはdockerグループに入っていますがrootではなく、containerdはDockerのために稼働するsystemdサービスです。
この環境では、Bashツールの呼び出しがコマンドの中身に関係なく、標準出力なしの終了コード1で終わります。次の条件が揃っているなら、この記事の症状です。
- エラー文が
bwrap: Can't mkdir parents for /run/containerd/containerd.sock: Permission deniedである /run/containerdがdrwx--x--x root:root(0711)である- 一般ユーザーで動かしている
3つ目の条件は、ホストの端末で確かめられます。
stat -c '%a %U:%G %n' /run/containerd /run/containerd/containerd.sock
bwrap --version報告者の環境では、ディレクトリが711 root:root、ソケットがsrw-rw---- root rootでした。ソケット自体は存在しているので、ファイルが無いことが原因ではありません。
なぜ権限エラーになるのか — straceが示したopenat2
報告者はstraceで、失敗した本当のシステムコールを突き止めています。致命的なのは、/run/containerdをディレクトリとして開く次の呼び出しです。
openat2(6, "/run/containerd", {flags=O_RDONLY|O_DIRECTORY,
resolve=RESOLVE_NO_MAGICLINKS|RESOLVE_IN_ROOT}, 24) = -1 EACCES同じトレースの前半では、bwrapは/run/containerd/containerd.sockをO_PATHで何度も開いて成功しています。O_PATHのopenは対象の読み取り権限を要求せず、祖先ディレクトリの実行(検索)権限だけを見ます。0711は全員に実行権限を与えるので、ここは通ります。
一方、O_DIRECTORYで実ディレクトリとして開くときは、カーネルが読み取り権限も確認します。0711は所有者以外には実行権限しかないため、EACCESになります。報告者によると、0711はクライアントが正確なパスでソケットに届きつつ、ディレクトリの中身を列挙できないようにするための、containerd側の意図した堅牢化です。
つまり、ホスト側の誤設定ではありません。
sandboxを無効にしても直らない理由
ここが、他のsandboxエラーと決定的に違う点です。報告では次の設定が、どれも効いていません。
| 試した設定 | 結果 |
|---|---|
.claude/settings.local.jsonで{"sandbox": {"enabled": false}} | 結果全コマンドが同じエラー |
ツール呼び出しにdangerouslyDisableSandbox: true | 結果変化なし |
/sandboxで無効表示を確認(「Sandbox disabled」) | 結果表示は無効でも、実行はbwrapを経由 |
さらに別の報告者は、GitHub Actionsで--settings '{"sandbox":{"enabled":false}}'を渡しました。SDKのデバッグログのSpawning Claude Code:行にその設定が逐語で届いていることを確認したうえで、echoがbwrapで落ちたと書いています。
公式ドキュメントは、sandboxが起動できないときの既定の動きを「依存が欠けている、またはプラットフォームが非対応なら、サンドボックスなしでコマンドを実行する」と説明しています。今回はbwrapが存在して起動し、その途中で失敗するので、この退避の対象にならないと読めます。failIfUnavailableも、依存の欠落時に起動を止める設定なので、この症状を直す手段ではありません。
設定に原因を求めても行き止まりになる、という点だけ覚えておけば、切り分けの時間を節約できます。sandbox.enabledの挙動そのものはsandbox.enabledの解説にあります。
bubblewrapの更新で突然再現する — Ubuntu 24.04の例
issueの3件目のコメントは、Claude Code側が変わっていないのに突然再現した例を示しています。anthropics/claude-code-actionでGitHub Actionsのubuntu-24.04ランナーを使うと、実行のたびにbubblewrapがaptで入ります。同じランナーイメージ、同じClaude Code(2.1.215)で、結果はbubblewrapのバージョンと一致しました。
| 時刻(UTC、2026-09-17) | 結果 | bubblewrap |
|---|---|---|
| 09:17〜14:35の6回 | 結果成功 | bubblewrap0.9.0-1ubuntu0.1 |
| 18:32、19:23、19:40 | 結果失敗 | bubblewrap0.9.0-1ubuntu0.2 |
| 19:52(下のchmodあり) | 結果成功 | bubblewrap0.9.0-1ubuntu0.2 |
0.9.0-1ubuntu0.2は、同日16:22 UTCにnoble-securityへ公開された更新です。報告者によれば、これはGHSA-pxhw-h44j-8pfxの修正(上流0.12.0)のバックポートで、宛先をシンボリックリンクをたどらずに作成・解決し、シンボリックリンクの宛先へのマウントを拒否する内容です。各パス成分を実ディレクトリとして開く実装なので、先ほどのopenat2のEACCESと符合します。
切り分けのために、報告者はClaude CodeもAPIキーも使わず、素のbwrapだけで確認しています。
bwrap --ro-bind / / \
--ro-bind /run/containerd/containerd.sock /run/containerd/containerd.sock \
true| 条件 | 終了コード |
|---|---|
| 0.9.0-1ubuntu0.2(archive) | 終了コード1(同じメッセージ) |
| 0.9.0-1ubuntu0.1(poolからdpkg -i) | 終了コード0 |
0.9.0-1ubuntu0.2 + chmod a+rx /run/containerd | 終了コード0 |
この結果から、問題は「0711の親ディレクトリを持つバインド先を、新しいbwrapが解決できない」ことで、Claude Codeのバージョンとは独立だと報告者は結論づけています。ディストリビューションが同じ修正を配るにつれて、containerdのあるホストで再現する範囲は広がる可能性があります。この予測は報告者の見立てで、公式の見解ではありません。
回避策と、それぞれが払う代償
issueでは、Claude Code側の修正は出ていません。コメントに挙がっている手は3つで、どれも副作用があります。
| 回避策 | 効く理由 | 代償 |
|---|---|---|
/run/containerdに読み取り権限を足す | 効く理由O_DIRECTORYで開けるようになる | 代償containerdの堅牢化を緩める |
| toolbx内でClaude Codeを動かす | 効く理由ホストの/run/containerdが見えない | 代償作業環境がコンテナに移る |
| 修正前のbubblewrapに戻す | 効く理由シンボリックリンク安全な解決が入る前の挙動 | 代償セキュリティ修正を外す |
3つ目の「修正前に戻す」は、Ubuntuで素のbwrapを使った上の実験が根拠で、報告者が推奨した手順ではありません。CVE対応のバックポートを外すことになるため、実運用に勧められる選択肢とは言えません。
chmodで読み取り権限を足す
CI向けに報告者が使っているのは次の1行です。
if [ -d /run/containerd ]; then sudo chmod a+rx /run/containerd; fiパッチ済みのbwrapはそのままで、シンボリックリンクの宛先を拒否する動きも残ります。変わるのはcontainerdの状態ディレクトリを誰でも列挙できるようになる点だけです。報告者のランナーで列挙したところ、名前は固定の6つで、ソケット2つはsrw-rw---- root rootのまま、3つのサブディレクトリは0700のまま、1つは0711のままでした。
報告者はこれを「使い捨てのシングルテナントCI VMなら許容できるが、共有ホストではやらない」と書いています。再起動やcontainerdの再作成でパーミッションが戻る場合もあるため、恒久化するならsystemdの設定側で扱う必要があります。この点はissueに書かれていない、一般的な注意です。
toolbxの中で動かす
最初の報告者は暫定策として、toolbx内でclaudeを動かす方法を挙げています。詳しい手順や制約はissueにありません。
報告者が示す修正の方向
issueは、bug、has repro、platform:linux、area:bash、area:sandboxのラベルが付いた不具合として扱われています。原因の読みは、二人の報告者のコメントに次のように出ています。
- 起票者は本文で、サンドボックスの起動処理がコンテナランタイムのソケットを無条件にマウントしようとしている、と推測しています。親ディレクトリの書き込み権限の確認や、設定による省略がないという見立てです
- 起票者はstrace後のコメントで、同じトレースで
/run/podman/podman.sockのEACCESは許容され、中断されていないと指摘しています。containerdだけがこの想定内の失敗を扱えていない、という読みです - 別の報告者は、共有ホストでは自分のchmodは使わず、Claude Code側が
EACCESを許容する形での修正が要る、と書いています
これらはいずれも報告者の分析で、Anthropicの回答はissueに付いていません。「どのコードがマウントを組み立てているか」は公式ドキュメントにも載っておらず、推測の域を出ない点に注意してください。
手元で原因を確かめる手順
自分の環境が同じ型かどうかは、Claude Codeを介さずに確かめられます。
# 1. bubblewrapのバージョンとパッケージ版
bwrap --version
dpkg -l bubblewrap | tail -1
# 2. 親ディレクトリのモード(711だと読み取り不可)
stat -c '%a %U:%G %n' /run/containerd
# 3. 素のbwrapで再現するか(Claude Codeを使わない)
bwrap --ro-bind / / \
--ro-bind /run/containerd/containerd.sock /run/containerd/containerd.sock \
true; echo "exit=$?"3の終了コードが1で同じメッセージなら、Claude Codeの設定ではなくbwrapとディレクトリ権限の組み合わせが原因です。0なら、このissueとは別の原因を疑うことになります。
Podmanのみを使うホストや、containerdが入っていないホストでは、この組み合わせ自体が成立しません。報告された条件はcontainerdのソケットが存在し、親が0711であるホストです。
GitHub Actionsで踏んだときの確認順
claude-code-actionの実行がある日を境に全部落ちるようになったら、ワークフローの変更より先に、その日のbubblewrapの更新を疑う価値があります。報告者の調べ方を踏まえると、確認の順序は次のようになります。
- 失敗した実行と成功した実行で、bubblewrapのパッケージ版を比べる
- ランナーイメージとClaude Codeのバージョンが同じかを確かめる
- 実行の最初に
/run/containerdの存在とモードをログへ出す - 許容できる環境なら、報告者のchmodを実行前の手順に入れる
ここで、公式ドキュメントが示すsandboxの設定項目は、今回の原因に届きません。公式のセキュリティ上の注意は、allowUnixSocketsで/var/run/docker.sockを通すとホストへのアクセスと同等になる、という内容です。ソケット周りは権限の影響が大きい領域です。権限を緩める回避策を採るなら、緩めた範囲を記録しておくと後で戻せます。
見分けたい近いエラー
bwrapが絡むエラーは文面ごとに原因が違います。メッセージの末尾で振り分けてください。
| メッセージ | 原因の型 |
|---|---|
Can't mkdir parents for /run/containerd/containerd.sock | 原因の型本記事。0711の親ディレクトリ |
execvp /bin/bash: No such file or directory | 原因の型merged-usrのシンボリックリンク不足。merged-usrの解説 |
Can't mount proc on /newroot/proc | 原因の型コンテナ内でのproc。公式はenableWeakerNestedSandboxを案内。設定の解説 |
NixOSでの権限エラーは構造が別なので、NixOSのsandbox権限エラーを参照してください。
公式のトラブルシューティングにあるenableWeakerNestedSandboxは、コンテナ内で/procをマウントできないときの設定で、今回のmkdir失敗とは別の話です。この設定が今回の症状を直す、という報告もありません。
Docker入りホストのチームが押さえておく点
この問題は、containerdが入っている一般ユーザーのホストなら、Claude Codeのバージョンにかかわらず起こり得ます。一方で、症状は「全Bashが止まる」というはっきりした形なので、更新後に急に出たときは、まずbwrap --versionと/run/containerdのパーミッションを見れば、原因のあたりがつきます。
sandboxを外せば逃げられる、という前提は崩れています。回避は権限の緩和か、環境の隔離か、bubblewrapの更新方針の見直しのどれかになり、どれを選ぶかはホストが共有かどうかで変わります。