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

  1. Check pageserver logs for why the stream or connection closed
  2. Lower --count below the server's and any proxy's concurrent-stream limits
  3. Ensure direct connectivity without intermediaries that reset idle streams
  4. 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

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


AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16). Data as JSON: /api/errors/33318d15361f4a26. Report an issue: GitHub.