Describe the bug
nitro panics with a nil-pointer SIGSEGV inside filtermaps on every single boot when starting a fresh full node from the current Arbitrum One pruned snapshot (arb1/2026-07-29-94e5135f). The node never produces a usable database, does not serve RPC/IPC, and does not make any progress across restarts — 18+ boots all crash at the identical point.
Reproduced identically on three releases: v3.11.2-3599aca, v3.11.1-8512b8c, v3.11.0-a618155.
To Reproduce
- Download the current pruned snapshot listed at
https://snapshot.arbitrum.foundation/arb1/latest-pruned.txt (currently arb1/2026-07-29-94e5135f/, shipped as 5 parts, pruned.tar.part0000–part0004, 2,553,385,195,520 bytes total).
- Extract into a fresh data directory (verified byte-for-byte: 2378.3 GiB extracted vs. 2378.0 GiB archive size; extraction tooling was custom but the output tree was independently checked against the tar's own file list — this is not an extraction artifact, see "What I've ruled out" below).
- Start nitro with:
--chain.id=42161
--parent-chain.connection.url=<alchemy eth-mainnet>
--parent-chain.blob-client.beacon-url=<publicnode beacon>
--node.feed.input.url=wss://arb1.arbitrum.io/feed
--ipc.path=/nitro-data/arbitrum.ipc
--http.addr=127.0.0.1 --http.port=8547 --http.api=net,web3,eth,arb
--node.staker.enable=false
--execution.caching.archive=false
(--init.latest=pruned was used for the original failed download attempt only; on this run the pre-extracted directory is mounted directly and no --init.* flags are passed.)
- Node boots, opens the database, then panics within ~10–90s every time.
Expected behavior
Node starts, replays the ~4 days between the snapshot date and chain head, and serves RPC.
Crash
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0xa90357]
goroutine 2692 [running]:
github.com/cockroachdb/pebble/objstorage/objstorageprovider.(*vfsReadHandle).ReadAt(...)
/go/pkg/mod/github.com/cockroachdb/pebble@v1.1.5/objstorage/objstorageprovider/vfs_readable.go:155 +0xb7
github.com/cockroachdb/pebble/sstable.(*Reader).readBlock(...)
/go/pkg/mod/github.com/cockroachdb/pebble@v1.1.5/sstable/reader.go:565 +0x310
github.com/cockroachdb/pebble/sstable.(*singleLevelIterator).loadBlock(...)
/go/pkg/mod/github.com/cockroachdb/pebble@v1.1.5/sstable/reader_iter_single_lvl.go:398 +0x297
github.com/cockroachdb/pebble/sstable.(*singleLevelIterator).skipForward(...)
/go/pkg/mod/github.com/cockroachdb/pebble@v1.1.5/sstable/reader_iter_single_lvl.go:1246 +0x46
github.com/cockroachdb/pebble/sstable.(*singleLevelIterator).Next(...)
/go/pkg/mod/github.com/cockroachdb/pebble@v1.1.5/sstable/reader_iter_single_lvl.go:1137 +0x10e
github.com/cockroachdb/pebble/sstable.(*twoLevelIterator).Next(...)
/go/pkg/mod/github.com/cockroachdb/pebble@v1.1.5/sstable/reader_iter_two_lvl.go:794 +0x34
github.com/cockroachdb/pebble.(*levelIter).Next(...)
/go/pkg/mod/github.com/cockroachdb/pebble@v1.1.5/level_iter.go:911 +0x153
github.com/cockroachdb/pebble.(*mergingIter).nextEntry(...)
/go/pkg/mod/github.com/cockroachdb/pebble@v1.1.5/merging_iter.go:620 +0xc2
github.com/cockroachdb/pebble.(*mergingIter).Next(...)
/go/pkg/mod/github.com/cockroachdb/pebble@v1.1.5/merging_iter.go:1254 +0x45
github.com/cockroachdb/pebble.(*Iterator).nextUserKey(...)
/go/pkg/mod/github.com/cockroachdb/pebble@v1.1.5/iterator.go:755 +0x166
github.com/cockroachdb/pebble.(*Iterator).nextWithLimit(...)
/go/pkg/mod/github.com/cockroachdb/pebble@v1.1.5/iterator.go:1872 +0x2b8
github.com/cockroachdb/pebble.(*Iterator).Next(...)
/go/pkg/mod/github.com/cockroachdb/pebble@v1.1.5/iterator.go:1663
github.com/ethereum/go-ethereum/ethdb/pebble.(*pebbleIterator).Next(...)
/workspace/go-ethereum/ethdb/pebble/pebble.go:884 +0x49
github.com/ethereum/go-ethereum/core/rawdb.SafeDeleteRange(...)
/workspace/go-ethereum/core/rawdb/database.go:798 +0x30f
github.com/ethereum/go-ethereum/core/rawdb.deletePrefixRange(...)
/workspace/go-ethereum/core/rawdb/accessors_indexes.go:667 +0x145
github.com/ethereum/go-ethereum/core/rawdb.DeleteBloomBitsDb(...)
/workspace/go-ethereum/core/rawdb/accessors_indexes.go:678 +0x4b
github.com/ethereum/go-ethereum/core/filtermaps.(*FilterMaps).safeDeleteWithLogs(...)
/workspace/go-ethereum/core/filtermaps/filtermaps.go:436 +0x17a
github.com/ethereum/go-ethereum/core/filtermaps.(*FilterMaps).removeBloomBits(...)
/workspace/go-ethereum/core/filtermaps/filtermaps.go:423 +0x68
created by github.com/ethereum/go-ethereum/core/filtermaps.(*FilterMaps).Start in goroutine 1
/workspace/go-ethereum/core/filtermaps/filtermaps.go:291 +0x148
Preceded on every boot by the same warnings against very old blocks (e.g. block=6,771,083, block=11,840,086, climbing within the run but starting fresh each boot):
INFO Found legacy ancient chain path location=/home/user/.arbitrum/arb1/nitro/l2chaindata/ancient
INFO Opened ancient database database=.../l2chaindata/ancient readonly=true
INFO Opened Era store datadir=.../l2chaindata/ancient/era
WARN Failed to decode block body block=6,771,083 error=EOF
CRIT Failed writing batch to db error="pebble: closed"
What I've ruled out / already tried
- Not an extraction problem. File count (207,281), zero-length files (11, all legitimate empty
LOCK/FLOCK markers), and total extracted size (2378.3 GiB vs. 2378.0 GiB archive) are all consistent. The database opens fine and Opened ancient database / Opened Era store both succeed before the crash.
--execution.rpc.log-no-history: still crashes, moves from removeBloomBits to reset in the same safeDeleteWithLogs call.
--execution.caching.state-scheme=path: rejected outright — error initializing database err="incompatible state scheme, stored: hash, provided: path". So the snapshot is hash-scheme, confirmed by nitro itself.
- Manually creating the
ancient/era directory that the "Opened Era store" log line references (it does not exist in the extracted snapshot): no change.
- Three different nitro versions (v3.11.2, v3.11.1, v3.11.0): byte-identical crash and stack in all three.
- Progress across restarts: none.
greping the highest block number touched in the logs returns the exact same value on every one of 18 consecutive boots.
Something that may be relevant
The snapshot's l2chaindata/ancient/ freezer is in the old flat layout (bodies.0000.cdat, bodies.0001.cdat, ... — files dated 2024-09-17), while classic-msg/ancient/ in the same snapshot uses the newer chain/ subdirectory layout (dated 2025-11-04). So the pruned snapshot appears to bundle a stale/legacy-format l2chaindata freezer inside an otherwise current export. This lines up with Found legacy ancient chain path being logged specifically for l2chaindata, and might be why the log-index rebuild (filtermaps) chokes on it while iterating.
Environment
- nitro image:
offchainlabs/nitro-node:v3.11.2-3599aca (also v3.11.1-8512b8c, v3.11.0-a618155)
- Host: bare-metal AMD Ryzen 9900X, Ubuntu 24.04, RAID0 NVMe, btrfs
- Container: Debian 12 LXC (Incus), 16 vCPU / 64GB RAM allocated, Docker 29.7.1 inside
- Chain data on a dedicated btrfs-backed volume, plenty of free space (not a disk-space issue — confirmed via
df/du throughout)
- Not OOM-killed (
OOMKilled=false in docker inspect, 63GB free at crash time)
Question
Is this pruned snapshot (arb1/2026-07-29-94e5135f) known to have a corrupted/legacy l2chaindata freezer, or is this a genuine filtermaps/legacy-ancient-freezer interop bug that would affect anyone starting fresh from it? Happy to provide the full extracted database or any further diagnostics if useful.
Describe the bug
nitropanics with a nil-pointer SIGSEGV insidefiltermapson every single boot when starting a fresh full node from the current Arbitrum One pruned snapshot (arb1/2026-07-29-94e5135f). The node never produces a usable database, does not serve RPC/IPC, and does not make any progress across restarts — 18+ boots all crash at the identical point.Reproduced identically on three releases:
v3.11.2-3599aca,v3.11.1-8512b8c,v3.11.0-a618155.To Reproduce
https://snapshot.arbitrum.foundation/arb1/latest-pruned.txt(currentlyarb1/2026-07-29-94e5135f/, shipped as 5 parts,pruned.tar.part0000–part0004, 2,553,385,195,520 bytes total).--init.latest=prunedwas used for the original failed download attempt only; on this run the pre-extracted directory is mounted directly and no--init.*flags are passed.)Expected behavior
Node starts, replays the ~4 days between the snapshot date and chain head, and serves RPC.
Crash
Preceded on every boot by the same warnings against very old blocks (e.g.
block=6,771,083,block=11,840,086, climbing within the run but starting fresh each boot):What I've ruled out / already tried
LOCK/FLOCKmarkers), and total extracted size (2378.3 GiB vs. 2378.0 GiB archive) are all consistent. The database opens fine andOpened ancient database/Opened Era storeboth succeed before the crash.--execution.rpc.log-no-history: still crashes, moves fromremoveBloomBitstoresetin the samesafeDeleteWithLogscall.--execution.caching.state-scheme=path: rejected outright —error initializing database err="incompatible state scheme, stored: hash, provided: path". So the snapshot is hash-scheme, confirmed by nitro itself.ancient/eradirectory that the "Opened Era store" log line references (it does not exist in the extracted snapshot): no change.greping the highest block number touched in the logs returns the exact same value on every one of 18 consecutive boots.Something that may be relevant
The snapshot's
l2chaindata/ancient/freezer is in the old flat layout (bodies.0000.cdat,bodies.0001.cdat, ... — files dated2024-09-17), whileclassic-msg/ancient/in the same snapshot uses the newerchain/subdirectory layout (dated2025-11-04). So the pruned snapshot appears to bundle a stale/legacy-formatl2chaindatafreezer inside an otherwise current export. This lines up withFound legacy ancient chain pathbeing logged specifically forl2chaindata, and might be why the log-index rebuild (filtermaps) chokes on it while iterating.Environment
offchainlabs/nitro-node:v3.11.2-3599aca(alsov3.11.1-8512b8c,v3.11.0-a618155)df/duthroughout)OOMKilled=falseindocker inspect, 63GB free at crash time)Question
Is this pruned snapshot (
arb1/2026-07-29-94e5135f) known to have a corrupted/legacyl2chaindatafreezer, or is this a genuinefiltermaps/legacy-ancient-freezer interop bug that would affect anyone starting fresh from it? Happy to provide the full extracted database or any further diagnostics if useful.