neondatabase/neon · error
no timelines found
Error message
no timelines found
What it means
idle_streams picks a victim timeline by calling targets::discover with limit_to_first_n_targets: Some(1). If the pageserver management API returns an empty timeline list, timelines.first() is None and the command fails with 'no timelines found' before opening any stream.
Source
Thrown at pageserver/pagebench/src/cmd/idle_streams.rs:58
async fn main_impl(args: Args) -> anyhow::Result<()> {
// Discover a tenant and timeline to use.
let mgmt_api_client = Arc::new(pageserver_client::mgmt_api::Client::new(
reqwest::Client::new(),
args.http_server.clone(),
None,
));
let timelines: Vec<TenantTimelineId> = crate::util::cli::targets::discover(
&mgmt_api_client,
crate::util::cli::targets::Spec {
limit_to_first_n_targets: Some(1),
targets: None,
},
)
.await?;
let ttid = timelines
.first()
.ok_or_else(|| anyhow!("no timelines found"))?;
// Set up the initial client.
let endpoint = Endpoint::from_shared(args.server.clone())?;
let connect = async || {
pageserver_page_api::Client::new(
endpoint.connect().await?,
ttid.tenant_id,
ttid.timeline_id,
ShardIndex::unsharded(),
None,
None,
)
};
let mut client = connect().await?;
let mut streams = Vec::with_capacity(args.count);
View on GitHub (pinned to 8f60b04da4)
Solutions
- Verify the management API endpoint, e.g. curl http://<host>:6400/v1/tenant returns a non-empty list
- Create or attach a tenant and timeline and wait until it reports active
- Re-run idle_streams once the tenant appears in the list
Example fix
# before idle_streams --mgmt-api-endpoint http://wrong-host:6400 ... # after # 1) confirm the tenant list is non-empty curl -s http://localhost:6400/v1/tenant | jq length # must be > 0 # 2) run the bench against the same endpoint idle_streams --mgmt-api-endpoint http://localhost:6400 ...
Defensive patterns
Strategy: validation
Validate before calling
let timelines = crate::util::cli::targets::discover(
&mgmt_api_client,
Spec { limit_to_first_n_targets: Some(1), targets: None },
).await?;
if timelines.is_empty() {
anyhow::bail!("no timelines on this pageserver; create or attach a tenant first");
} Try / catch
let ttid = match timelines.first() {
Some(ttid) => *ttid,
None => {
eprintln!("no timelines found: check --mgmt-api-endpoint and tenant state");
return Err(anyhow!("no timelines found"));
}
}; Prevention
- Smoke-test GET /v1/tenant before running discovery-based benches
- Wait for tenant activation (poll until active) after creating tenants
- Keep management-API and page_service endpoints in distinct documented variables
When it happens
Trigger: Running idle_streams against a pageserver with zero attached tenants; pointing --mgmt-api-endpoint at the wrong host or at the page_service port so the tenant list comes back empty; all tenants deleted or in a state excluded from listing.
Common situations: A fresh dev or staging pageserver before any tenant is created; after tenant migration or deletion; port confusion between the management API and other listeners.
Related errors
- pageserver has less than limit_to_first_n_targets={limit} te
- must specify exactly one target
- invalid connstring: {err}
- invalid scheme {scheme}
- unexpected status code: {}
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/ebbfcb8b40b74944.
Report an issue: GitHub.