{"record":{"id":"1c68ee5299f08723","repo":"neondatabase/neon","slug":"err","errorCode":null,"errorMessage":"{err}","messagePattern":"\\{err\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pageserver/pagebench/src/cmd/getpage_latest_lsn.rs","lineNumber":759,"sourceCode":"        rel: RelTag,\n        blks: Vec<u32>,\n    ) -> anyhow::Result<()> {\n        let req = page_api::GetPageRequest {\n            request_id: req_id.into(),\n            request_class: page_api::GetPageClass::Normal,\n            read_lsn: page_api::ReadLsn {\n                request_lsn: req_lsn,\n                not_modified_since_lsn: Some(mod_lsn),\n            },\n            rel,\n            block_numbers: blks,\n        };\n        let inner = self.inner.clone();\n        self.requests.push(Box::pin(async move {\n            inner\n                .get_page(req)\n                .await\n                .map_err(|err| anyhow::anyhow!(\"{err}\"))\n        }));\n        Ok(())\n    }\n\n    async fn recv_get_page(&mut self) -> anyhow::Result<(u64, Vec<Bytes>)> {\n        let resp = self.requests.next().await.unwrap()?;\n        Ok((\n            resp.request_id.id,\n            resp.pages.into_iter().map(|p| p.image).collect(),\n        ))\n    }\n}\n","sourceCodeStart":741,"sourceCodeEnd":772,"githubUrl":"https://github.com/neondatabase/neon/blob/8f60b04da47ffefe0e52bda2440134b42874eb75/pageserver/pagebench/src/cmd/getpage_latest_lsn.rs#L741-L772","documentation":"The gRPC variant of getpage_latest_lsn maps every tonic transport or status error from Client::get_page into anyhow with the raw message text. It fires when the RPC fails before a valid response is produced: channel closed, connection refused or dropped mid-run, stream reset, deadline exceeded, or an error Status returned by the pageserver handler.","triggerScenarios":"pageserver restart, crash, or OOM during the run; the gRPC endpoint not enabled or the wrong port used; a handler panic surfacing as an Unknown status; proxies or load balancers killing the long-lived channel.","commonSituations":"Passing the libpq page_service port where the gRPC listener is expected; long benches crossing idle or keepalive timeouts of intermediaries; environments where DNS changes mid-run invalidate the endpoint.","solutions":["Verify the gRPC page_api listener address and that it is enabled in the pageserver configuration","Inspect pageserver logs and panics around the failure time","Re-run the bench once; transient transport failures are common","Raise or disable keepalive and idle timeouts on any proxy between client and server"],"exampleFix":"// before\ninner.get_page(req).await.map_err(|err| anyhow::anyhow!(\"{err}\"))\n// after: retry once on transient transport failure\nmatch inner.clone().get_page(req.clone()).await {\n    Ok(resp) => Ok(resp),\n    Err(status) if matches!(status.code(), tonic::Code::Unavailable | tonic::Code::DeadlineExceeded) => {\n        inner.get_page(req).await.map_err(|err| anyhow::anyhow!(\"{err}\"))\n    }\n    Err(err) => Err(anyhow::anyhow!(\"{err}\")),\n}","handlingStrategy":"retry","validationCode":"async fn endpoint_reachable(addr: &str) -> bool {\n    tokio::net::TcpStream::connect(addr).await.is_ok()\n}","typeGuard":null,"tryCatchPattern":"match inner.get_page(req).await {\n    Ok(resp) => resp,\n    Err(status) => {\n        let code = status.code();\n        if matches!(code, tonic::Code::Unavailable | tonic::Code::DeadlineExceeded) {\n            // rebuild the channel from the Endpoint and retry the call once\n        }\n        anyhow::bail!(\"get_page failed: {status}\")\n    }\n}","preventionTips":["Pre-check TCP reachability of the gRPC endpoint before the bench","Use the same host:port the pageserver logs as its gRPC listen address","Wrap long benches in an outer retry loop that tolerates one reconnect","Watch server memory; OOM kills surface here as Unavailable"],"tags":["pagebench","grpc","tonic","network","transport"],"backgroundTag":"grpc-call-failed","analyzedSha":"8f60b04da47ffefe0e52bda2440134b42874eb75","analyzedAt":"2026-08-16T23:39:28.135Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}