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

  1. Switch the caller to a shard-aware listing (iterate shards via the mgmt API per TenantShardId) instead of the unsharded helper
  2. Or only point the helper at pageservers guaranteed to host unsharded tenants exclusively
  3. Identify the sharded tenant from the error message and handle its shards separately
  4. 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

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


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