You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The History Publish (Testnet) job Test History Publish now fast-fails (~38–82 s) by the validator process dying during catchup, distinct from the checkpoint-publish timeout/runner-cancel mode tracked by #3741. The node downloads all buckets, begins restore_from_has_parallel (disk-backed mode), loads levels 0–10, then aborts parsing a bucket entry:
INFO henyey_history::catchup::buckets: apply_buckets START — RSS 166 MB
INFO henyey_history::catchup::buckets: Applying buckets to build state at ledger 4378879 (disk-backed mode)
...
INFO henyey_bucket::bucket_list: restore_from_has_parallel: loaded level curr+snap level=10 curr_entries=5774175 snap_entries=0 elapsed_ms=6718
ERROR henyey_app::run_cmd: Node stopped with error error=catchup failed: Failed to restore live bucket list:
bucket serialization error: Failed to parse bucket entry at offset 4483092: xdr value invalid
Error: catchup failed: Failed to restore live bucket list: bucket serialization error:
Failed to parse bucket entry at offset 4483092: xdr value invalid
##[error]Process completed with exit code 1.
failure (fast-fail; log expired, same mode by duration)
Head sha: 129190c0 (current origin/main HEAD) — NOT the deployed validator binary 0ac84d42.
Each daily run catches up to the then-current testnet checkpoint (here target_ledger=4378879), i.e. a different bucket set each run. A parse failure recurring across days on different checkpoints argues a systematic deserialization defect, not a one-off corrupt download.
crates/bucket/src/disk_bucket.rs:228 — stellar_xdr::BucketEntry::from_xdr(record.body, Limits::none()) returns Err → crates/bucket/src/disk_bucket.rs:232-235 formats Failed to parse bucket entry at offset {}: {} (BucketError::Serialization).
Record framing comes from self.records.next_record() (disk_bucket.rs:212); the raw mark_bytes+body are fed to the hasher before parse (:222-224), so a framing/offset mis-split would corrupt record.body.
Propagates via crates/history/src/catchup/buckets.rs:450 → HistoryError::CatchupFailed("Failed to restore live bucket list: …").
Hypotheses (to be triaged)
Record framing / offset drift in next_record() — a mis-read length prefix would hand from_xdr misaligned bytes and produce "xdr value invalid" at a plausible-looking offset. Offset 4483092 is deep in the largest (level-10, 5.77 M-entry) bucket.
A BucketEntry variant henyey's XDR can't decode on a recent testnet bucket (protocol/type the deserializer rejects). Would be a genuine parity gap.
Recently introduced on main (present on 129190c0, deployed 0ac84d42 predates it) — bisect 0ac84d42..129190c0 over crates/bucket/ and the vendored stellar_xdr pin.
Why this matters beyond CI
restore_from_has_parallel is the same code path used by the operator-only cold-catchup recovery for the current mainnet outage (#3905 / #3702: recovery = wipe + cold catchup, which restores the live bucket list from a HAS). If this deserialization defect also affects mainnet buckets on 129190c0, a binary carrying it could fail the recovery catchup. (Not yet confirmed on mainnet buckets — mainnet cold-catchup last succeeded 2026-07-01 on 0ac84d42.) Flagging so a fix lands before any redeploy off 0ac84d42.
Suggested next steps
Pull the failing testnet bucket for checkpoint 4378879 and reproduce offline: parse level-10 curr bucket, locate the record at offset 4483092, and inspect whether framing or the entry body is at fault.
Compare next_record() framing against stellar-core's bucket record format for the entry preceding offset 4483092.
Add a regression test around disk_bucket.rs record framing on a real testnet bucket fixture.
Distinct from #3741 (checkpoint-publish timeout/cancel) — filing separately per the different subsystem + root cause; Related to #3741.
Filed by monitor-tick (validator is separately down under #3905; this is a CI-surfaced correctness finding on 129190c0).
Symptom
The History Publish (Testnet) job
Test History Publishnow fast-fails (~38–82 s) by the validator process dying during catchup, distinct from the checkpoint-publish timeout/runner-cancel mode tracked by #3741. The node downloads all buckets, beginsrestore_from_has_parallel(disk-backed mode), loads levels 0–10, then aborts parsing a bucket entry:Evidence
129190c0(currentorigin/mainHEAD) — NOT the deployed validator binary0ac84d42.target_ledger=4378879), i.e. a different bucket set each run. A parse failure recurring across days on different checkpoints argues a systematic deserialization defect, not a one-off corrupt download.Code path (file:line)
crates/bucket/src/disk_bucket.rs:228—stellar_xdr::BucketEntry::from_xdr(record.body, Limits::none())returnsErr→crates/bucket/src/disk_bucket.rs:232-235formatsFailed to parse bucket entry at offset {}: {}(BucketError::Serialization).self.records.next_record()(disk_bucket.rs:212); the rawmark_bytes+bodyare fed to the hasher before parse (:222-224), so a framing/offset mis-split would corruptrecord.body.crates/history/src/catchup/buckets.rs:450→HistoryError::CatchupFailed("Failed to restore live bucket list: …").Hypotheses (to be triaged)
next_record()— a mis-read length prefix would handfrom_xdrmisaligned bytes and produce "xdr value invalid" at a plausible-looking offset. Offset 4483092 is deep in the largest (level-10, 5.77 M-entry) bucket.BucketEntryvariant henyey's XDR can't decode on a recent testnet bucket (protocol/type the deserializer rejects). Would be a genuine parity gap.main(present on129190c0, deployed0ac84d42predates it) — bisect0ac84d42..129190c0overcrates/bucket/and the vendoredstellar_xdrpin.Why this matters beyond CI
restore_from_has_parallelis the same code path used by the operator-only cold-catchup recovery for the current mainnet outage (#3905 / #3702: recovery = wipe + cold catchup, which restores the live bucket list from a HAS). If this deserialization defect also affects mainnet buckets on129190c0, a binary carrying it could fail the recovery catchup. (Not yet confirmed on mainnet buckets — mainnet cold-catchup last succeeded 2026-07-01 on0ac84d42.) Flagging so a fix lands before any redeploy off0ac84d42.Suggested next steps
4378879and reproduce offline: parse level-10 curr bucket, locate the record at offset 4483092, and inspect whether framing or the entry body is at fault.next_record()framing against stellar-core's bucket record format for the entry preceding offset 4483092.disk_bucket.rsrecord framing on a real testnet bucket fixture.Distinct from #3741 (checkpoint-publish timeout/cancel) — filing separately per the different subsystem + root cause; Related to #3741.
Filed by monitor-tick (validator is separately down under #3905; this is a CI-surfaced correctness finding on
129190c0).