neondatabase/neon · error
Error: {:?}
Error message
Error: {:?} What it means
`PagestreamReceiver::getpage_recv` awaited a GetPage response on the pageserver's pagestream channel but received `PagestreamBeMessage::Error` instead — the pageserver itself rejected or failed the request (bad LSN, missing relation, tenant/timeline issues) and reported the reason in the embedded error struct, which this message formats with Debug.
Source
Thrown at pageserver/client/src/page_service.rs:236
pub async fn getpage_send(&mut self, req: PagestreamGetPageRequest) -> anyhow::Result<()> {
self.send(PagestreamFeMessage::GetPage(req)).await
}
}
impl PagestreamReceiver {
// TODO: maybe make this impl Stream instead for better composability?
pub async fn recv(&mut self) -> anyhow::Result<PagestreamBeMessage> {
let next: Option<Result<bytes::Bytes, _>> = self.stream.next().await;
let next: bytes::Bytes = next.unwrap()?;
PagestreamBeMessage::deserialize(next)
}
pub async fn getpage_recv(&mut self) -> anyhow::Result<PagestreamGetPageResponse> {
let next: PagestreamBeMessage = self.recv().await?;
match next {
PagestreamBeMessage::GetPage(p) => Ok(p),
PagestreamBeMessage::Error(e) => anyhow::bail!("Error: {:?}", e),
PagestreamBeMessage::Exists(_)
| PagestreamBeMessage::Nblocks(_)
| PagestreamBeMessage::DbSize(_)
| PagestreamBeMessage::GetSlruSegment(_) => {
anyhow::bail!(
"unexpected be message kind in response to getpage request: {}",
next.kind()
)
}
#[cfg(feature = "testing")]
PagestreamBeMessage::Test(_) => {
anyhow::bail!(
"unexpected be message kind in response to getpage request: {}",
next.kind()
)
}
}
}View on GitHub (pinned to 8f60b04da4)
Solutions
- Inspect the Debug-formatted error struct in the message — it carries the pageserver's actual failure reason and code
- Check pageserver logs at the corresponding time for the detailed server-side error
- Validate the LSN and relation you request against the timeline's known range before retrying
- If the server reports a missing layer/tenant issue, resolve that on the pageserver first
Defensive patterns
Strategy: try-catch
Try / catch
match pagestream.getpage_recv().await {
Ok(page) => { /* use page */ }
Err(e) if e.to_string().starts_with("Error:") => {
// pageserver-reported failure: inspect reason, validate LSN/relation, then retry or surface
return Err(e.context("pageserver rejected getpage request"));
}
Err(e) => return Err(e),
} Prevention
- Validate requested LSNs against the timeline's last record LSN before sending getpage
- Correlate client-side pagestream errors with pageserver logs by timestamp
- Retry only idempotent reads after confirming the server-side cause
When it happens
Trigger: Sending a getpage request that the pageserver cannot serve: requesting an LSN beyond the timeline, a nonexistent relation/block, or hitting a server-side error while reconstructing the page; the server replies with an Error message rather than GetPage.
Common situations: Compute requesting a page at an invalid/too-new LSN; timeline deleted or not yet attached; pageserver layer corruption or read errors during page reconstruction.
Related errors
- unexpected be message kind in response to getpage request: {
- invalid tag {tag}
- Non-overlapping bounds: other.max = {} was less than self.mi
- Non-overlappinng bounds: self.max = {} was less than other.m
- Unsupported key decoded at LSN {}: {}
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/ce6fc6a85ad0c8b5.
Report an issue: GitHub.