Tested fix · Updated
MongoDB cannot start: Linux kernel versions 6.19 and newer has a known incompatibility with this version of MongoDB
On GitHub-hosted runners the kernel is already fixed. Only MongoDB's version check reads it wrong. The ubuntu-24.04 runner image 20261018.339.1 runs Ubuntu kernel 7.0.0-1017-azure, GitHub's maintainers reproduced the same exit on ubuntu-26.04, and ubuntu-latest fails with them. The check in MongoDB 8.0.21–8.0.34, 8.3.0–8.3.13 and 9.0.2 reads uname -r, sees 7.0.0 and exits. Ubuntu builds that kernel from upstream 7.0.14, which MongoDB's own notes list as fixed.
MongoDB 9.0.4 prints a second form of the same error on kernels it still blocks:
MongoDB cannot start: Linux kernel versions 6.19.0 through 7.0.13 have a known incompatibility with this version of MongoDB. See https://jira.mongodb.org/browse/SERVER-121912 for more information.
Both lines carry log id 12257600. In Actions logs the same failure has been reported as ##[error]Failed to initialize container mongo:8.0 for a service container, and as MongoDB did not initialize within 20 seconds. Exiting. from supercharge/.
Fixes, by situation
On a GitHub-hosted runner, pick one:
Use
mongo:9.0.4. It reads the kernel's real upstream version on Ubuntu and starts as it is.mongo:9andmongo:latestpoint to 9.0.4 today. This is a major-version change, so check your application against MongoDB 9 first.Stay on 8.0 or 8.3 and set one variable on the container:
services: mongodb: image: mongo:8.0 env: GLIBC_TUNABLES: glibc.pthread.rseq=1 ports: - 27017:27017With that variable in mongod's environment, 8.0.34, 8.3.13 and 9.0.2 started in our test under the runner's kernel strings; ping, an insert and a find all worked. We set it inside each official image. We did not run this YAML on Actions, but a service container's
env:sets the same container variable, and a public project's CI passes with exactly this change (lolevbeer/site #307). Withdocker run, add-e GLIBC_TUNABLES=; with Compose, put it underglibc. pthread. rseq= 1 environment:.The cost: TCMalloc's per-CPU caches go off.
db.changed fromserverStatus(). tcmalloc. usingPerCPUCaches truetofalsein every image we ran, andmaxPerCPUCacheSizeBytesdropped from 33554432 (32 MiB) to 1572864 (1.5 MiB). We did not measure the speed difference. Treat it as a CI workaround, and measure before you use it in production.Using
supercharge/? Release 1.12.1 has no way to pass container environment. Itsmongodb-github-action mainbranch has had amongodb-extra-envinput since 21 April 2026, and Payum's CI passes with it (Payum/Payum#1070). Pin the commit you use. We read the input's source but did not run the action.- uses: supercharge/mongodb-github-action@<commit on main> with: mongodb-version: "8.0" mongodb-extra-env: GLIBC_TUNABLES=glibc.pthread.rseq=1Run the job on
ubuntu-22.04. This is the workaround GitHub's runner-images maintainers recommend in actions/runner-images#15005. They report that MongoDB 8.3.13 passed there; we did not test it. It moves the whole job to an older OS, not just the database.Pin
mongo:8.2ormongo:8.0.20. These have no startup check. 8.2.12 and 8.0.20 started in our test under the runner's kernel strings with per-CPU caches on. MongoDB's compatibility table lists 8.0.0–8.0.20 as supported on 7.0.14 and later, and the runner kernel is 7.0.14 by its version signature. You give up the fixes in later 8.0 releases, and MongoDB marks 8.0.0–8.0.20 "DO NOT USE" on an unfixed kernel (below). MongoDB's table also lists 7.0 as supported on every kernel; we did not run 7.0.
Which tag you have now: mongo:8 and mongo:8.3 are 8.3.13, mongo:8.0 is 8.0.34, all of which exit on these runners (read from Docker Hub on 22 October 2026, 11:28 UTC).
On your own Ubuntu host (24.04 HWE kernel, or 26.04), read the last field of /proc/version_signature. If it is 7.0.14 or later, the kernel is fixed and the runner advice above applies. If it is 7.0.13 or earlier, see Other kernels.
Why it fires
The check has two conditions. It stops mongod only if both are true.
1. The kernel version, as MongoDB reads it, is in the blocked range. In 8.0.34, 8.3.13 and 9.0.2 the test is this line from src/, applied to uname -r:
return version < std::array{6, 19, 0} || std::array{7, 0, 13} < version;Ubuntu keeps the release string at X.Y.0 for the life of a kernel series and puts the upstream patch level elsewhere. On the runners:
uname -r # 7.0.0-1017-azure (what 8.x reads: 7.0.0)
cat /proc/version_signature # last field: 7.0.14 (the upstream version)So every Ubuntu 7.0 kernel looks like 7.0.0, inside 6.19.0–7.0.13, whatever it contains. MongoDB tracks this as SERVER-131779. 9.0.4 has that fix: when the release starts with 7.0 and uname -v contains Ubuntu, it reads the version from /proc/version_signature instead. That is why 9.0.4 starts on the runners and why it still exits, with the second message, on an Ubuntu kernel whose signature says 7.0.13.
2. TCMalloc's per-CPU caches are active. The guard exists for them: MongoDB says a change to restartable sequences (rseq) in kernel 6.19 broke TCMalloc, its memory allocator, until 7.0.14 and 7.1 restored the old behaviour (SERVER-121912, SERVER-125742). TCMalloc can use rseq only if glibc has not registered it first, so the official images set, in each Dockerfile:
ENV GLIBC_TUNABLES glibc.pthread.rseq=0glibc.pthread.rseq=1 lets glibc register rseq itself. TCMalloc then falls back to per-thread caches, condition 2 is false, and the check passes whatever the kernel. In all 77 runs, mongod exited only when per-CPU caches would have been on. Unsetting GLIBC_TUNABLES had the same effect as rseq=1 in our runs. To see which mode a running server is in:
mongosh --quiet --eval 'db.serverStatus().tcmalloc.usingPerCPUCaches'Which versions check what
The rule comes from startup_check_rseq.cpp at each release tag. "Ran" means we started that image; other rows are from the source only.
| MongoDB | Startup check | GitHub runner (7.0.0-1017-azure, upstream 7.0.14), image default | Evidence |
|---|---|---|---|
| 8.0.0–8.0.20 | none | starts | ran 8.0.20; MongoDB's table for the rest |
| 8.0.21–8.0.29 | any kernel 6.19 or later, 7.1 included | exits | ran 8.0.29; source for the other tags |
| 8.0.30–8.0.34 | uname -r in 6.19.0–7.0.13 | exits | ran 8.0.34; source for 8.0.30, 8.0.32 |
| 8.1.x, 8.2.x | none | starts | ran 8.2.12; source for 8.1 |
| 8.3.0–8.3.8 | any kernel 6.19 or later, 7.1 included | exits | source only |
| 8.3.9–8.3.13 | uname -r in 6.19.0–7.0.13 | exits | ran 8.3.13; source for 8.3.9, 8.3.11 |
| 9.0.2 | uname -r in 6.19.0–7.0.13 | exits | ran 9.0.2 |
| 9.0.4 | 6.19.0–7.0.13, Ubuntu 7.0 kernels judged by /proc/version_signature | starts | ran 9.0.4 |
| 8.0.35, 8.3.14 | same as 9.0.4, per SERVER-131779 | not yet published | — |
With GLIBC_TUNABLES=, every image we ran started on every kernel profile we tried.
Other kernels: Fedora, Arch, unfixed Ubuntu
Here the release string is the upstream version, or the Ubuntu signature really is 7.0.13 or older, so the kernel itself may lack the fix.
- 6.19.x to 7.0.13 (for example Fedora's
6.19.8-200.fc43.x86_64): 8.0.29, 8.0.34, 8.3.13, 9.0.2 and 9.0.4 all exited at startup under these strings. Update the kernel to 7.0.14 or later, or 7.1.rseq=1got every one of them past the check, but our test machine's real kernel was 6.8, so we have not tested whether MongoDB is then safe on an unfixed kernel. Do not treatrseq=1, 8.0.20 or 8.2 as safe there. 8.0.20 and 8.2.12 start on these kernels with per-CPU caches on, and MongoDB's table marks 8.0.0–8.0.20 "DO NOT USE" on 6.19–7.0.13, saying it crashes after about 60 seconds. We did not test crashes. - 7.1.x: 8.0.34, 8.3.13, 9.0.2 and 9.0.4 started. 8.0.29 still exited: 8.0.21–8.0.29 and 8.3.0–8.3.8 block every kernel from 6.19 on, so move to a newer patch release.
Check a version before you run it
This POSIX shell script predicts the startup check from the rules in the table. It reads uname, /proc/version_signature and, with --image, the MONGO_VERSION and GLIBC_TUNABLES of an image you have pulled. It runs nothing from MongoDB. Exit status: 0 starts, 1 exits at startup, 2 starts but the kernel is in MongoDB's crash range, 3 usage. Its predictions matched all 77 of our runs.
sh mongo-kernel-check.sh --image mongo:8.0
sh mongo-kernel-check.sh 8.0.34 glibc.pthread.rseq=1Run it as a workflow step to check the runner itself. To check another machine, pass its values:
KREL=7.0.0-1017-azure KVER='#17~24.04.1-Ubuntu SMP' \
KSIG='Ubuntu 7.0.0-1017.17~24.04.1-azure 7.0.14' sh mongo-kernel-check.sh 8.0.34 glibc.pthread.rseq=0kernel: uname -r 7.0.0-1017-azure; upstream 7.0.14 (from /proc/version_signature)
mongodb 8.0.34: check=uname; TCMalloc per-CPU caches active: yes (GLIBC_TUNABLES=glibc.pthread.rseq=0)
RESULT: EXITS at startup with id 12257600 ("MongoDB cannot start: Linux kernel versions 6.19 ...")
This kernel already has the fix (upstream 7.0.14 >= 7.0.14); only the version check stops it.
Options: run it with GLIBC_TUNABLES=glibc.pthread.rseq=1 (per-CPU caches off, so the check does not fire),
or a release that reads this kernel correctly (9.0.4 today; 8.0.35 / 8.3.14 when published).mongo-kernel-check.sh, complete (sha256 1a372bfd22a5c3dfecd311f4c373be6f5817cc49483ba0bb0ef9aaf6172d9db2):
#!/bin/sh
# mongo-kernel-check.sh — will this MongoDB start on this Linux kernel?
#
# Predicts MongoDB's startup kernel check (log id 12257600, SERVER-121912) from the
# rules in src/mongo/db/startup_check_rseq.cpp at each release tag. Runs nothing from
# MongoDB; reads uname, /proc/version_signature and (optionally) an image's env.
#
# sh mongo-kernel-check.sh 8.0.34 # bare mongod, env from this shell
# sh mongo-kernel-check.sh 8.0.34 glibc.pthread.rseq=0 # say what GLIBC_TUNABLES will be
# sh mongo-kernel-check.sh --image mongo:8 # read MONGO_VERSION/GLIBC_TUNABLES
# # from a pulled image (docker inspect)
# KREL=7.0.0-1017-azure KVER='#17~24.04.1-Ubuntu SMP' \
# KSIG='Ubuntu 7.0.0-1017.17~24.04.1-azure 7.0.14' sh mongo-kernel-check.sh 8.0.34 glibc.pthread.rseq=0
# # check another machine's values
# Exit status: 0 starts, 1 exits at startup, 2 starts but kernel is in the crash range, 3 usage.
# CyberNative AI LLC, 2026-10-22. SPDX-License-Identifier: MIT. It predicts the startup check
# only; it cannot tell whether a kernel crashes MongoDB. The crash range is MongoDB's statement.
set -eu
if [ "${1:-}" = "--image" ]; then
img=${2:?image name}
envs=$(docker image inspect -f '{{range .Config.Env}}{{println .}}{{end}}' "$img")
ver=$(printf '%s\n' "$envs" | sed -n 's/^MONGO_VERSION=//p')
tun=$(printf '%s\n' "$envs" | sed -n 's/^GLIBC_TUNABLES=//p')
[ -n "$ver" ] || { echo "no MONGO_VERSION in $img"; exit 3; }
echo "image $img: MONGO_VERSION=$ver GLIBC_TUNABLES=${tun:-<unset>} (an env: or -e setting overrides this)"
else
ver=${1:-}; tun=${2-${GLIBC_TUNABLES:-}}
[ -n "$ver" ] || { sed -n '2,15p' "$0"; exit 3; }
fi
krel=${KREL:-$(uname -r)}
kver=${KVER-$(uname -v)}
ksig=${KSIG-$(head -n1 /proc/version_signature 2>/dev/null || true)}
num() { printf '%s' "$1" | sed 's/[^0-9.].*//'; } # 7.0.0-1017-azure -> 7.0.0
cmp3() { # prints -1/0/1 comparing a.b.c with x.y.z
awk -v a="$1" -v b="$2" 'BEGIN{split(a,p,".");split(b,q,".");
for(i=1;i<=3;i++){if(p[i]+0<q[i]+0){print -1;exit}if(p[i]+0>q[i]+0){print 1;exit}}print 0}'; }
in_range() { [ "$(cmp3 "$1" 6.19.0)" -ge 0 ] && [ "$(cmp3 "$1" 7.0.13)" -le 0 ]; }
kup=$(num "$krel")
upstream=$kup
case "$ksig" in Ubuntu\ *) upstream=$(num "${ksig##* }");; esac
echo "kernel: uname -r $krel; upstream ${upstream}${ksig:+ (from /proc/version_signature)}"
mv=$(num "$ver"); maj=${mv%%.*}; rest=${mv#*.}; min=${rest%%.*}
# Rule per release line (read at tags r8.0.18..r8.0.34, r8.1.*, r8.2.*, r8.3.0..r8.3.13, r9.0.2, r9.0.4):
if [ "$maj" -lt 8 ] || { [ "$maj" = 8 ] && { [ "$min" = 1 ] || [ "$min" = 2 ]; }; } \
|| { [ "$maj.$min" = 8.0 ] && [ "$(cmp3 "$mv" 8.0.20)" -le 0 ]; }; then
rule=none # 8.0.0-8.0.20, 8.1, 8.2: no startup check (7.x: per MongoDB's matrix)
elif { [ "$maj.$min" = 8.0 ] && [ "$(cmp3 "$mv" 8.0.29)" -le 0 ]; } \
|| { [ "$maj.$min" = 8.3 ] && [ "$(cmp3 "$mv" 8.3.8)" -le 0 ]; }; then
rule=all619 # blocks every kernel >= 6.19
elif { [ "$maj.$min" = 8.0 ] && [ "$(cmp3 "$mv" 8.0.34)" -le 0 ]; } \
|| { [ "$maj.$min" = 8.3 ] && [ "$(cmp3 "$mv" 8.3.13)" -le 0 ]; } \
|| { [ "$maj.$min" = 9.0 ] && [ "$(cmp3 "$mv" 9.0.3)" -le 0 ]; }; then
rule=uname # blocks uname -r 6.19.0-7.0.13, so every Ubuntu 7.0.0-* kernel
else
rule=ubuntu # 8.0.35+, 8.3.14+, 9.0.4+: Ubuntu kernels judged by version_signature
# (later release lines are assumed to keep the 9.0.4 rule)
fi
# Per-CPU caches are active only when TCMalloc owns rseq, i.e. glibc was told not to
# register it (glibc.pthread.rseq=0, which the official mongo images set).
percpu=no; case "$tun" in *glibc.pthread.rseq=0*) percpu=yes;; esac
echo "mongodb $ver: check=$rule; TCMalloc per-CPU caches active: $percpu (GLIBC_TUNABLES=${tun:-<unset>})"
blocked=no
if [ "$percpu" = yes ]; then
case $rule in
all619) [ "$(cmp3 "$kup" 6.19.0)" -ge 0 ] && blocked=yes ;;
uname) in_range "$kup" && blocked=yes ;;
ubuntu) case "$kver" in *Ubuntu*) [ "$krel" = "${krel#7.0}" ] || kup=$upstream;; esac
in_range "$kup" && blocked=yes ;;
esac
fi
if [ "$blocked" = yes ]; then
echo "RESULT: EXITS at startup with id 12257600 (\"MongoDB cannot start: Linux kernel versions 6.19 ...\")"
if in_range "$upstream"; then
echo " This kernel (upstream $upstream) lacks the rseq fix: update it to 7.0.14+ or 7.1+."
echo " GLIBC_TUNABLES=glibc.pthread.rseq=1 gets past the check, but whether MongoDB is then safe"
echo " on an unfixed kernel is untested."
else
echo " This kernel already has the fix (upstream $upstream >= 7.0.14); only the version check stops it."
echo " Options: run it with GLIBC_TUNABLES=glibc.pthread.rseq=1 (per-CPU caches off, so the check does not fire),"
echo " or a release that reads this kernel correctly (9.0.4 today; 8.0.35 / 8.3.14 when published)."
fi
exit 1
fi
if [ "$percpu" = yes ] && in_range "$upstream"; then
echo "RESULT: STARTS, but upstream $upstream is in 6.19.0-7.0.13, where MongoDB says it crashes after ~60 s"
echo " with per-CPU caches on. Update the kernel to 7.0.14+ or 7.1+."
exit 2
fi
echo "RESULT: STARTS (the kernel check does not stop it)"When to undo the workaround
MongoDB lists 8.0.35, 8.3.14 and 9.0.4 as the releases with the Ubuntu fix. On 22 October 2026 at 11:28 UTC, Docker Hub had 9.0.4 but no mongo:8.0.35 or mongo:8.3.14. When those tags appear, remove GLIBC_TUNABLES= and move back from ubuntu-22.04, 8.0.20 or 8.2 pins. By MongoDB's fix list, mongo:8.0 and mongo:8 should then start on the runners with per-CPU caches on; the checker already treats 8.0.35 and 8.3.14 that way.
How we tested
Run on 22 October 2026, 10:23–11:19 UTC, with the official Docker Hub images pulled by index digest:
| Image | Digest |
|---|---|
mongo:8.0.20 | sha256:098862b1339f031900ca66cf8fef799e616d6324fa41b9a263f2ec899552c1ef |
mongo:8.0.29 | sha256:02a0cc7939f5ed38f30f9bc714ef5f682d49baf9350c54acf302ce833087fe8a |
mongo:8.0.34 | sha256:4a4ab5d4834207389e0d7270fac988e21ffedccecba77991a552f755df229907 |
mongo:8.2.12 | sha256:e0ce8c35124d4a9f9785532d1f268f39e9728ffa1cb38f46fa482436424c4bd3 |
mongo:8.3.13 | sha256:0e900a3364da37b76d642b73b0bba56bd4c6c509ab470cf700436fd866bee3ff |
mongo:9.0.2 | sha256:f5c6240ae8fccc21cf75acc6462929b3394a7a5a7abd934b6b0e7ada5eb5fe95 |
mongo:9.0.4 | sha256:dc28ed5a9d0fc616903c3f463bb1e53b92b49f441721b91926e87d90bf957ce8 |
Method, and its limit. Our host runs Ubuntu kernel 6.8. mongod in these images is dynamically linked against glibc, so we preloaded a small LD_PRELOAD library that changes only what uname() returns and what /proc/version_signature contains. Each image ran without network, with mongod started directly (not through the image's entrypoint), once per kernel profile and GLIBC_TUNABLES setting. A run counted as starting at "Waiting for connections", followed by ping, one insert and one find with the image's mongosh, and a read of db.. rseq, the scheduler and TCMalloc's CPU detection were the real 6.8 kernel's. So these runs show what the startup check does with each kernel's version strings, and what GLIBC_TUNABLES does to the per-CPU caches. They show nothing about crashes on a real 6.19–7.0.13 kernel.
Kernel profiles (strings we composed; the build date in uname -v is filler): runner 7.0.0-1017-azure, uname -v containing Ubuntu, signature Ubuntu 7.0.0-1017.17~24.04.1-azure 7.0.14; Ubuntu unfixed the same with 1016 and 7.0.13; 7.1.3 with no signature; Fedora 6.19.8-200.fc43.x86_64 with no signature; and the host's own 6.8.
Results with the image default GLIBC_TUNABLES=:
| Image | Host 6.8 | Runner 7.0.0 / 7.0.14 | Ubuntu 7.0.0 / 7.0.13 | 7.1.3 | Fedora 6.19.8 |
|---|---|---|---|---|---|
| 8.0.20 | starts | starts | starts, crash range | starts | starts, crash range |
| 8.0.29 | starts | exits | exits | exits | exits |
| 8.0.34 | starts | exits | exits | starts | exits |
| 8.2.12 | starts | starts | starts, crash range | starts | starts, crash range |
| 8.3.13 | starts | exits | exits | starts | exits |
| 9.0.2 | starts | exits | exits | starts | exits |
| 9.0.4 | starts | starts | exits (second message) | starts | exits (second message) |
"Crash range" means per-CPU caches were on with a kernel version MongoDB says crashes; our real kernel was 6.8, so nothing crashed and nothing was tested there. With GLIBC_TUNABLES=, all 35 runs started with usingPerCPUCaches false. With the variable unset, on the runner profile, all 7 images started with usingPerCPUCaches false. Every exit was code 1 with log id 12257600; 9.0.4 printed the "6.19.0 through 7.0.13" message and the other images the "6.19 and newer" one. 77 runs in all.
Not tested: crash behaviour or rseq=1 safety on a real 6.19–7.0.13 kernel, the speed cost of rseq=1, GitHub Actions service-container env: and the supercharge action as such, ubuntu-22.04 runners, MongoDB 7.0, 8.1, 8.0.21–8.0.28 and 8.3.0–8.3.12 individually, Azure DevOps hosted agents, and arm64.