neondatabase/neon · error · BasebackupError
invalid {:?} record: block.len()={}
Error message
invalid {:?} record: block.len()={} What it means
The same SLRU segment builder validates pg_multixact_offsets and pg_multixact_members page images: they must be exactly BLCKSZ. Any other length means the multixact SLRU page reconstructed from layers is malformed, and the basebackup aborts with the SLRU kind and offending length in the message.
Source
Thrown at pageserver/src/basebackup.rs:268
total_blocks: 0,
}
}
async fn add_block(&mut self, key: &Key, block: Bytes) -> Result<(), BasebackupError> {
let (kind, segno, _) = key.to_slru_block()?;
match kind {
SlruKind::Clog => {
if !(block.len() == BLCKSZ as usize || block.len() == BLCKSZ as usize + 8) {
return Err(BasebackupError::Server(anyhow!(
"invalid SlruKind::Clog record: block.len()={}",
block.len()
)));
}
}
SlruKind::MultiXactMembers | SlruKind::MultiXactOffsets => {
if block.len() != BLCKSZ as usize {
return Err(BasebackupError::Server(anyhow!(
"invalid {:?} record: block.len()={}",
kind,
block.len()
)));
}
}
}
let segment = (kind, segno);
match self.current_segment {
None => {
self.current_segment = Some(segment);
self.buf
.extend_from_slice(block.slice(..BLCKSZ as usize).as_ref());
}
Some(current_seg) if current_seg == segment => {
self.buf
.extend_from_slice(block.slice(..BLCKSZ as usize).as_ref());View on GitHub (pinned to 8f60b04da4)
Solutions
- Check pageserver logs for the failing key and layer
- Retry the basebackup at a different LSN to see whether the damage is LSN-bounded
- Validate or re-download the implicated layers from remote storage
- If corruption is confirmed, recover from a healthy branch or backup
Example fix
// before: size checked only inside the builder during basebackup
// after: validate on read so callers learn the key, not just the length
let (kind, segno, blk) = key.to_slru_block()?;
if kind.is_multixact() && img.len() != 8192 {
anyhow::bail!("corrupt {kind:?} page seg {segno} blk {blk}: len {}", img.len());
} Defensive patterns
Strategy: validation
Validate before calling
// scrub multixact SLRU blocks ahead of a backup window
for kind in [SlruKind::MultiXactOffsets, SlruKind::MultiXactMembers] {
for key in scan_slru_keys(kind).await? {
let img = timeline.get(key, lsn, ctx).await?;
if img.len() != 8192 {
alert_corruption(ttid, key, img.len());
}
}
} Type guard
fn is_valid_slru_page(kind: SlruKind, img: &bytes::Bytes) -> bool {
match kind {
SlruKind::Clog => matches!(img.len(), 8192 | 8200),
_ => img.len() == 8192,
}
} Try / catch
Err(e) if e.to_string().contains("record: block.len()") => {
// parse the kind and length from the message; open a corruption investigation
} Prevention
- Schedule layer validation between backup windows
- Alert on any basebackup abort mentioning block.len()
- Keep multixact-heavy workloads on monitored tenants
- Cross-check remote object checksums after uploads
When it happens
Trigger: A MultiXactMembers or MultiXactOffsets block image with size != 8192 served during basebackup: layer corruption, a reconstruction bug for multixact keys, or page-layout skew from version changes.
Common situations: Workloads with heavy shared-row locking (multixacts) hitting a damaged layer; branches spanning neon versions with multixact format changes.
Related errors
- invalid SlruKind::Clog record: block.len()={}
- img.len() != SIZE_OF_RELMAPFILE, img.len()={}
- backup_prev {backup_prev} != provided_prev_lsn {provided_pre
- pageserver connection information should be provided
- shard {shard_index} missing from pageserver_connection_info
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/31f90cfa7ca56f54.
Report an issue: GitHub.