Repository navigation
[Bug]: linux-arm64 CLI from nightly 20261022.3512 cannot exec on 16 KiB-page kernels (Raspberry Pi 5) #23433
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
Build, CI, or release tooling
Steps to reproduce
On a linux-arm64 host whose kernel uses 16 KiB pages (getconf PAGESIZE prints 16384). This includes a Raspberry Pi 5 on its default rpi-2712 kernel.
npx t3@0.1.2-nightly.20261022.3512 --version- Or run the extracted binary directly:
~/.t3/runtime/versions/0.1.2-nightly.20261022.3512/t3 --version
Expected behavior
It prints t3 v0.1.2-nightly.20261022.3512, as 0.1.2-nightly.20261021.3499 does on the same machine.
Actual behavior
The kernel refuses to load the binary. The shell shows Segmentation fault and exit code 139:
$ strace -f ~/.t3/runtime/versions/0.1.2-nightly.20261022.3512/t3 --version
execve(".../0.1.2-nightly.20261022.3512/t3", [..., "--version"], ...) = -1 EINVAL (Invalid argument)
+++ killed by SIGSEGV +++
Through npx it prints nothing at all. The npm launcher (bin/t3.mjs) turns the child's SIGSEGV into process.exit(139) without a message, so the command just seems to do nothing.
Cause
The two newest LOAD segments in the 3512 binary are aligned to 4 KiB (0x1000). A kernel with 16 KiB pages cannot map them. In 3499, every LOAD segment is aligned to 64 KiB.
readelf -lW t3, 3499 (works):
LOAD 0x000000 0x0000000000400000 ... 0x409510 0x409510 R 0x10000
LOAD 0x410000 0x0000000000810000 ... 0x2978c90 0x2978c90 R E 0x10000
LOAD 0x2d90000 0x0000000003190000 ... 0x3dfd208 0x3dfd208 R 0x10000
LOAD 0x6b8d208 0x0000000006f8d208 ... 0x06dca8 0x0bedf8 RW 0x10000
LOAD 0x8dde000 0x0000000010dde000 ... 0xffe000 0xffe000 R 0x10000 <- .note.node.sea
3512 (fails):
PHDR 0x6dad000 0x00000000071ad000 ... 0x0002a0 0x0002a0 R 0x8
LOAD 0x000000 0x0000000000400000 ... 0x41d390 0x41d390 R 0x10000
LOAD 0x420000 0x0000000000820000 ... 0x29d82f0 0x29d82f0 R E 0x10000
LOAD 0x2e00000 0x0000000003200000 ... 0x3eda298 0x3eda298 R 0x10000
LOAD 0x6cdee00 0x00000000070eee00 ... 0x0bdb00 0x0bdb00 RW 0x10000
LOAD 0x6dad000 0x00000000071ad000 ... 0x000508 0x000508 R 0x1000 <- new segment holding the moved program headers
LOAD 0x8faf000 0x000000001015d000 ... 0x1003000 0x1003000 R 0x1000 <- .note.node.sea, was 0x10000
The only build change between the two nightlies is #23165 (ed9b7ca), which moved the single-executable from Node 26.8.2 to 26.12.1. The binaries confirm this: 3499 embeds v26.8.2, 3512 embeds v26.12.1. So the --build-sea injector in Node 26.12.1 now writes 4 KiB-aligned segments on linux-arm64. 26.8.2 did not.
The arm64 smoke test can't catch this, because GitHub's arm64 runners use 4 KiB pages. A build-time check would catch it: fail the linux-arm64 archive if any LOAD in readelf -lW has an alignment below 0x10000.
Impact
Blocks work completely
Version or commit
0.1.2-nightly.20261022.3512 (3b95e78). Last working: 0.1.2-nightly.20261021.3499 (b5a226e).
Environment
Raspberry Pi 5 Model B Rev 1.1, Debian 13 (trixie), kernel 6.18.50+rpt-rpi-2712 (16 KiB pages), node v22.23.2 for npx
Logs or stack traces
See above. dmesg shows nothing; the failure is at execve.
Activity
Skeptomenos commentedon Oct 22, 2026
Same crash on Apple Silicon under Asahi Linux, which also runs a 16 KiB-page kernel. It now affects the preview channel too, not only nightly, and it is still present in the newest nightly.
Environment
7.1.13-402.asahi.fc44.aarch64+16kgetconf PAGESIZE→16384; glibc 2.43npm install -g t3@<version>), run as at3 serveuser serviceBuilds tested (
t3 --version)0.1.1(latest)0.1.2-nightly.20261021.34990.1.2-preview.20261022.3516(preview)0.1.2-nightly.20261022.3541(release archive, checksum verified againstSHA256SUMS)readelf -lW t3, preview 3516 (3541 is identical apart from the size of the last segment):Working 3499, all segments 64 KiB-aligned:
This matches the layout in this issue and in #23477 / #23773. Because the defect has reached
preview, a promotion tolatestwould break every Linux arm64 host with 16 KiB pages (Asahi on Apple Silicon, Raspberry Pi 5 default kernel). We have pinnedlatest0.1.1 until a fixed build ships, and can test a candidate build on Asahi.— drafted by David Helmus's agent
Project516 commentedon Oct 22, 2026
This now affects the stable channel too. The
v0.1.2release (Latest) has the same problem on a Raspberry Pi 5.6.18.50+rpt-rpi-2712,getconf PAGESIZEprints16384t3-0.1.2-linux-arm64.tar.gz(sha256 matchesSHA256SUMS):./t3 --versionexits 139 withSegmentation fault, every time0.1.1works on the same machinet3 update --yesfrom 0.1.1 fails in the staged binary check (PinnedRuntimeInstallError...Process interrupted due to receipt of signal: 'SIGSEGV'), so the background service stays on 0.1.1. The update aborts cleanly, but stable Pi 5 users are stuck on 0.1.1 until this is fixed.stefansedich commentedon Oct 22, 2026
This is also an issue trying to use the t3 kit with a Docker Sandbox on an M5 Mac https://hub.docker.com/r/sbx/t3code-kit
dbjohnson commentedon Oct 23, 2026
Local workaround for 16 KiB-page hosts until #23443 ships. Tested on Apple Silicon running Arch Linux ARM with the Asahi kernel (
7.2.12-1-1-ARCH,getconf PAGESIZE= 16384, glibc 2.43), with0.1.2-nightly.20261022.3541.The crash comes from the two LOAD segments that LIEF adds during SEA injection:
0x71ad000shares a 16 KiB page with the end of.bss, which ends at0x71ac900. The kernel maps it read-only over that page, and the first write to the tail of.bssfaults..note.node.seasegment has file offset0x8faf000and vaddr0x1015d000, and the two aren't congruent mod 16 KiB.The script below rewrites only virtual addresses in the headers; file contents stay where they are. It gives each 4 KiB-aligned LOAD segment a vaddr congruent to its file offset mod 64 KiB, placed past the previous segment's last 64 KiB page, and sets its alignment to
0x10000.PT_PHDR,PT_NOTEand section addresses inside a moved segment move with it. Node finds the SEA blob by walkingPT_NOTEheaders, so it still finds it. The moved PHDR segment no longer sits atfirst LOAD vaddr + e_phoff, so kernels older than 5.18 (which computeAT_PHDRthat way) won't load the result. I've only tested on 7.2.After patching, 3541 gives:
The other native files in the archive (
resource-monitor,node-pty,keyring,ffi-rs,fff, the Cursor SDK binaries) are already 64 KiB-aligned and needed no changes.To get a
t3 serviceinstall onto the new version, pre-stage the patched build. The updater skips the download when~/.t3/runtime/versions/<version>/t3exists with a matching.install-complete, and then runs the preflight against the staged binary:Then run the update from the app. My service went from
0.1.1-nightly.20261020.3411to 3541, and the launcher recorded it ascommitted.realign-elf-16k.pyThis is a stopgap; the real fix is aligning these segments at build time, as #23443 does.
christhomas commentedon Oct 23, 2026
Shouldn't a pipeline test have picked this up? I think this also needs to be added here cause it sounds like a very mechanical fault. Something quite easy to check