neondatabase/neon · error
only unsharded tenants are supported at this time: {}
Error message
only unsharded tenants are supported at this time: {} What it means
`get_pageserver_tenant_timelines_unsharded` is a mgmt-api convenience helper that lists every timeline on a pageserver and fails fast if any tenant is sharded. It exists for callers that can only reason about unsharded tenants; encountering a `TenantShardId` with a shard count means the helper's precondition is violated.
Source
Thrown at pageserver/client/src/mgmt_api/util.rs:21
use std::sync::Arc;
use pageserver_api::shard::TenantShardId;
use tokio::task::JoinSet;
use utils::id::{TenantId, TenantTimelineId};
use super::Client;
/// Retrieve a list of all of the pageserver's timelines.
///
/// Fails if there are sharded tenants present on the pageserver.
pub async fn get_pageserver_tenant_timelines_unsharded(
api_client: &Arc<Client>,
) -> anyhow::Result<Vec<TenantTimelineId>> {
let mut timelines: Vec<TenantTimelineId> = Vec::new();
let mut tenants: Vec<TenantId> = Vec::new();
for ti in api_client.list_tenants().await? {
if !ti.id.is_unsharded() {
anyhow::bail!(
"only unsharded tenants are supported at this time: {}",
ti.id
);
}
tenants.push(ti.id.tenant_id)
}
let mut js = JoinSet::new();
for tenant_id in tenants {
js.spawn({
let mgmt_api_client = Arc::clone(api_client);
async move {
(
tenant_id,
mgmt_api_client
.tenant_details(TenantShardId::unsharded(tenant_id))
.await
.unwrap(),
)View on GitHub (pinned to 8f60b04da4)
Solutions
- Switch the caller to a shard-aware listing (iterate shards via the mgmt API per TenantShardId) instead of the unsharded helper
- Or only point the helper at pageservers guaranteed to host unsharded tenants exclusively
- Identify the sharded tenant from the error message and handle its shards separately
- If sharding was unintentional, investigate how the tenant got sharded before proceeding
Example fix
// before: fails if any tenant is sharded
let timelines = get_pageserver_tenant_timelines_unsharded(&client).await?;
// after: shard-aware listing
for ti in client.list_tenants().await? {
if ti.id.is_unsharded() {
// handle unsharded tenant timelines
} else {
// handle sharded tenant via its shard ids
}
} Defensive patterns
Strategy: validation
Validate before calling
for ti in api_client.list_tenants().await? {
if !ti.id.is_unsharded() {
// handle or reject sharded tenants before using the unsharded-only helper
anyhow::bail!("sharded tenant {} present; use shard-aware listing", ti.id);
}
} Type guard
fn all_unsharded(tenants: &[TenantInfo]) -> bool {
tenants.iter().all(|ti| ti.id.is_unsharded())
} Prevention
- Prefer shard-aware APIs in any environment where sharding may be enabled
- Gate unsharded-only helpers behind an environment check on pageserver tenant state
- Document which scripts/tools assume unsharded tenants and monitor for shard creation
When it happens
Trigger: Calling `get_pageserver_tenant_timelines_unsharded(api_client)` against a pageserver that hosts at least one tenant whose `TenantShardId` reports a non-zero shard count (e.g. after the tenant was split into shards).
Common situations: Running legacy tooling or scripts against a pageserver after sharding was enabled for some tenants; control scripts written before sharding existed; test fixtures accidentally creating sharded tenants.
Related errors
- can't reduce shard count from {} to {}
- can't change stripe size from {} to {}
- no shards provided
- too many shards: {n}
- stripe size must be given for sharded tenants
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/d7136f2aebb25c14.
Report an issue: GitHub.