ubuntu-latest(Ubuntu 26.04)は /etc/sysctl.conf を読まない:inotify の「too many open files」と ThreadSanitizer の「unexpected memory mapping」
ubuntu-latest は、2026年10月19日から11月19日にかけて Ubuntu 24.04 から 26.04 に移ります(ほかに変わること)。イメージを作る処理はカーネルの設定をいくつか /etc/sysctl.conf に書きますが、26.04 では起動時にこのファイルを読むものがありません。systemd にこのファイルを読ませていた /etc/sysctl.d/99-sysctl.conf のリンクを、Ubuntu が外したためです(Launchpad #2084376・Won't Fix)。ランナーはカーネルの既定値のままで、担当者が x64 と Arm64 で確認しています(runner-images #15108):
fs.inotify.max_user_instances:1280 ではなく 128fs.inotify.max_user_watches:655360 ではなく 64097vm.mmap_rnd_bits:28 ではなく、x64 では Ubuntu のカーネルの既定の 32
vm.max_map_count も同じファイルにありますが、Ubuntu 26.04 の既定がもともと 1048576 なので影響はありません。
値を戻すステップ
#15108 の担当者の返事からです。ウォッチャーやクラスターを始める前、ジョブの最初に置きます。24.04 ではイメージにすでにある値を入れ直すだけなので、どちらでも害はありません:
- name: Restore kernel parameters run: sudo sysctl -w fs.inotify.max_user_instances=1280 fs.inotify.max_user_watches=655360 vm.mmap_rnd_bits=28
このステップを要らなくするイメージの変更は runner-images #15146 で提案されていて、11月4日の時点では取り込まれていません。ubuntu-slim はコンテナとして動き、これらの上限をホストのカーネルから受け取るので、どちらにしても自分の sysctl の設定は使われません。
.NET:「The configured user limit (128) on the number of inotify instances has been reached」
Host.CreateDefaultBuilder・WebApplication.CreateBuilder・WebApplicationFactory が作るホストは、どれも appsettings.json を見張り、そのために inotify のインスタンスを1つ開きます。テストごとにホストを作るテストは、すぐに 128 に届きます(sillsdev/serval #1077):
System.IO.IOException : The configured user limit (128) on the number of inotify instances has been reached, or the per-process limit on the number of open file descriptors has been reached. at System.IO.FileSystemWatcher.StartRaisingEvents() at Microsoft.Extensions.FileProviders.PhysicalFileProvider.Watch(String filter) ... at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateHost(IHostBuilder builder)
#15108 の報告者は、24.04 では緑だったテストが 26.04 では 389 件中 187 件落ちました。上のステップのほかに、テストのホストに設定ファイルを見張らせない手もあります。fingerprintjs/dotnet-sdk #221 はテストのアセンブリのモジュール初期化子で変数を設定し、ubuntu-latest のジョブが .NET 8・9・10 で通っています:
[ModuleInitializer]
internal static void DisableConfigReloadOnChange() =>
Environment.SetEnvironmentVariable("DOTNET_hostBuilder__reloadConfigOnChange", "false");
環境変数にするのは、WebApplication.CreateBuilder が ConfigureWebHost より前にこれを読むからです(mgasca/calendar #31:上限 128 のままで 153 件中 153 件が通過)。これでテストがランナーの上限に左右されなくなります。
kind・k3s などのクラスター:「too many open files」
inotify の上限は名前空間で分かれないので、Docker の中のクラスターのノードのコンテナもポッドも、すべてランナーの 128 を分け合います。ポッドが起動時に落ち、テストはその起動を待ってタイムアウトします。メッセージはウォッチャーを開いたプログラムによって違います:
- kind の上の Tekton:
failed to create fsnotify watcher: too many open files(tektoncd/cli #3393) - kind の上の Falco:
couldn't initialize inotify: too many open files。サイドカーが証明書のウォッチャーを余分に開く mTLS のジョブで特に多く出ます(falco-operator #470) - k3s:「failed to create image import watcher」と「too many open files」(gcpemu #899)
- クラスターの中の .NET のアプリが、上の節のメッセージで落ちる(dapr #10931)
4つとも、クラスターを作る前にランナーの上限を上げています。上限はランナーのカーネルのものなので、上のステップはジョブの中で、クラスターを用意するより前に置きます。kind も既知の問題に同じ直し方を載せています。26.04 では kind へのイメージの読み込みも落ちることがあります:Ubuntu 26.04 の kind load docker-image。
ThreadSanitizer:「unexpected memory mapping」
mmap のランダム化が 32 ビットだと、それに対応していない ThreadSanitizer のランタイムはプログラムが始まる前に止まります。CMake の構成中に、TSan でビルドした protoc から(valkey-search #1615):
FATAL: ThreadSanitizer: unexpected memory mapping 0x5d2e629f1000-0x5d2e62a20000
新しいランタイムは、ASLR を切ってプログラムを始め直そうとします。コンテナの中ではそれが許されないことがあり、別のメッセージで止まります(python-pillow/docker-images #292):
FATAL: ThreadSanitizer: encountered an incompatible memory layout but was unable to disable ASLR (perhaps sandboxing is enabled?). FATAL: Please rerun with lower ASLR entropy, ASLR disabled, and/or sandboxing disabled.
どちらのプロジェクトも、24.04 の値の vm.mmap_rnd_bits=28 をランナーで設定しています。コンテナはランナーのカーネルを使うので、sudo sysctl はコンテナの中ではなく、docker run の前にランナーで動かします。valkey-search によれば、GCC 13 と 14 は古いランタイムで、GCC 15 のランタイムは始め直すので、新しいツールチェーンではこのステップが要らなくなるかもしれません(valkey-search #1619)。コンテナではなくランナーの上なら、setarch "$(uname -m)" -R で1つのコマンドだけを ASLR なしで動かせます。
見分け方
cat /proc/sys/fs/inotify/max_user_instancesは、影響を受ける 26.04 のイメージでは 128、24.04 では 1280 と出ます。sysctl vm.mmap_rnd_bitsは 32 か 28 と出ます。- 「Set up job」を見ます。Runner Image のグループに
ubuntu-26.04かubuntu-24.04と出ます。11月19日までは、やり直しが 24.04 に当たって通ることがあるので、やり直しで緑になっても何も証明されません。runs-on: ubuntu-24.04は、GitHub が 24.04 を引退させるまでは持ちます。 - ステップのあとも「too many open files」が残るなら、別の上限かもしれません。inotify ではなく、1つのプロセスが開けるファイル記述子の数(
ulimit -n)です。
26.04 のほかの失敗
- Ubuntu 26.04 の「client version ... is too old」:Docker 29 は API 1.40 より古いクライアントを断るので、古い Testcontainers は「Could not find a valid Docker environment」で落ちます。
- Ubuntu 26.04 の kind load docker-image:Docker 29 の containerd イメージストアは pull したイメージの1つのプラットフォームの分しか持たないので、kind の読み込みが「ctr: content digest ... not found」で落ちます。
- Ubuntu 26.04 の bubblewrap:
bwrapの中のサンドボックスが、AppArmor のbwrap-userns-restrictの下で落ちます。 - 「coreutils: unknown program」:基本のコマンドのほとんどが uutils です。
- Ubuntu 26.04 の sudo -E:
sudoは-Eを無視する sudo-rs です。 - Ubuntu 26.04 の apt:名前が変わった・無くなったパッケージ。
失敗したジョブを IntelliJ IDEA から見るなら
Pipeline Inbox for GitHub Actions Workflows は、Lesstep が作っている JetBrains IDE(2024.1 以降)のプラグインです。すべてのリポジトリの実行を、ジョブ・ステップと一緒に IDE のツールウィンドウに並べ、いまのブランチの実行はステータスバーに出ます。読むのは無料、失敗したジョブの再実行・キャンセル・ワークフローの実行・デプロイのレビューは Pro(月 US$1.50・30日の無料試用つき)です。
GitHub と GitHub Actions は GitHub, Inc. の商標、Ubuntu は Canonical Ltd. の商標、.NET は Microsoft Corporation の商標、IntelliJ IDEA は JetBrains s.r.o. の商標です。このページは GitHub, Inc.・Canonical・Microsoft・JetBrains のいずれとも提携しておらず、承認も受けていません。
ほかに:「The ubuntu-latest label will migrate to Ubuntu 26」 · Ubuntu 26.04 の bubblewrap · 「coreutils: unknown program」 · IntelliJ IDEA で使える GitHub Actions のプラグインの比較 · English