neondatabase/neon · error
no response
Error message
no response
What it means
After sending a GetPage request on the page_api stream, idle_streams awaits the next response. Some(Err(..)) is surfaced via transpose()?, but None means the server closed the stream without answering, which becomes 'no response'. The remote side terminated the stream: connection loss, HTTP/2 GOAWAY, stream reset, or server shutdown.
Source
Thrown at pageserver/pagebench/src/cmd/idle_streams.rs:111
request_id: 1.into(),
request_class: GetPageClass::Normal,
read_lsn: ReadLsn {
request_lsn: Lsn::MAX,
not_modified_since_lsn: Some(Lsn(1)),
},
rel: RelTag {
spcnode: 1664, // pg_global
dbnode: 0, // shared database
relnode: 1262, // pg_authid
forknum: 0, // init
},
block_numbers: vec![0],
})?;
let resp = resp_stream
.next()
.await
.transpose()?
.ok_or_else(|| anyhow!("no response"))?;
if resp.status_code != GetPageStatusCode::Ok {
return Err(anyhow!("{} response", resp.status_code));
}
}
// Hold onto streams to avoid closing them.
streams.push((req_tx, resp_stream));
}
info!("opened {} streams, sleeping", args.count);
// Block forever, to hold the idle streams open for inspection.
futures::future::pending::<()>().await;
Ok(())
}
View on GitHub (pinned to 8f60b04da4)
Solutions
- Check pageserver logs for why the stream or connection closed
- Lower --count below the server's and any proxy's concurrent-stream limits
- Ensure direct connectivity without intermediaries that reset idle streams
- Re-run after the pageserver is confirmed healthy
Example fix
// before
let resp = resp_stream
.next()
.await
.transpose()?
.ok_or_else(|| anyhow!("no response"))?;
// after: distinguish error, clean close, and response
let resp = match resp_stream.next().await {
Some(Ok(resp)) => resp,
Some(Err(e)) => return Err(e.into()),
None => {
return Err(anyhow!(
"server closed the stream before responding; check pageserver logs"
))
}
}; Defensive patterns
Strategy: retry
Try / catch
// treat 'no response' as reconnect-and-retry, not fatal
loop {
match open_stream_and_probe(&args).await {
Ok(pair) => break pair,
Err(e) if e.to_string().contains("no response") => {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
continue;
}
Err(e) => return Err(e),
}
} Prevention
- Bound --count by the server's max concurrent streams setting
- Avoid load balancers between pagebench and pageserver for stream tests
- Monitor server-side stream close reasons in logs during the run
- Reconnect with fresh channels instead of reusing possibly-dead ones
When it happens
Trigger: The pageserver closing the stream after an internal error or during shutdown; opening more concurrent streams (--count) than the server or an intermediary permits; HTTP/2 connection teardown between request and response.
Common situations: High --count values tripping max-concurrent-streams limits; proxies or load balancers resetting idle or long-lived streams; pageserver restart while the bench holds streams open.
Related errors
- {err}
- unexpected status code: {}
- error downloading extension {:?}: {:?}
- no grpc_url for shard {shard_index}
- Failed to upload all blocks {:#?}
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/33318d15361f4a26.
Report an issue: GitHub.