{"record":{"id":"903745bb9527cdac","repo":"neondatabase/neon","slug":"tenant-shard-not-found","errorCode":null,"errorMessage":"Tenant shard not found","messagePattern":"Tenant shard not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"control_plane/storcon_cli/src/main.rs","lineNumber":1449,"sourceCode":"            \"Waiting for tenant shard {tenant_shard_id} to be migrated to node {until_migrated_to}\"\n        );\n    }\n\n    loop {\n        let desc = storcon_client\n            .dispatch::<(), TenantDescribeResponse>(\n                Method::GET,\n                format!(\"control/v1/tenant/{}\", tenant_shard_id.tenant_id),\n                None,\n            )\n            .await?;\n\n        // Output the current state of the tenant shard\n        let shard = desc\n            .shards\n            .iter()\n            .find(|s| s.tenant_shard_id == tenant_shard_id)\n            .ok_or(anyhow::anyhow!(\"Tenant shard not found\"))?;\n        let summary = format!(\n            \"attached: {} secondary: {} {}\",\n            shard\n                .node_attached\n                .map(|n| format!(\"{n}\"))\n                .unwrap_or(\"none\".to_string()),\n            shard\n                .node_secondary\n                .iter()\n                .map(|n| n.to_string())\n                .collect::<Vec<_>>()\n                .join(\",\"),\n            if shard.is_reconciling {\n                \"(reconciler active)\"\n            } else {\n                \"(reconciler idle)\"\n            }\n        );","sourceCodeStart":1431,"sourceCodeEnd":1467,"githubUrl":"https://github.com/neondatabase/neon/blob/8f60b04da47ffefe0e52bda2440134b42874eb75/control_plane/storcon_cli/src/main.rs#L1431-L1467","documentation":"watch_tenant_shard fetched the tenant description (GET control/v1/tenant/{tenant_id}) successfully, but no entry in desc.shards has a tenant_shard_id equal to the requested one. The tenant exists, but the specific shard (tenant id + shard number + count) does not. The command bails with this anyhow error from the Option::ok_or.","triggerScenarios":"Passing a TenantShardId whose shard number/count does not match the tenant's actual sharding — for example shard 1 of an unsharded tenant that only has shard 0, or a stale shard count after the tenant was resharded (split/merged) — to tenant-shard-watch or tenant-shard-describe.","commonSituations":"Watching a shard with a hardcoded id after the tenant's shard count changed; assuming a tenant is sharded when it is unsharded (only shard 0000 exists); copy-pasting a tenant_shard_id from another environment; the shard was detached or merged away between listing and watching.","solutions":["Describe the tenant and list its actual shards (their shard numbers and shard count) to get a valid tenant_shard_id","For an unsharded tenant, use shard number 0 with the unsharded count (e.g. <tenant_id>-0000 style id)","Re-check the tenant_shard_id for typos and confirm it comes from the same storage controller"],"exampleFix":"# before: tenant is unsharded, only shard 0 exists\nstorcon_cli tenant-shard-watch --tenant-shard-id <tenant_id>-0002-8\n# after\nstorcon_cli tenant-shard-watch --tenant-shard-id <tenant_id>-0000","handlingStrategy":"validation","validationCode":"// Validate the tenant_shard_id against the describe response before watching\nlet desc: TenantDescribeResponse = client\n    .dispatch(Method::GET, format!(\"control/v1/tenant/{}\", tenant_shard_id.tenant_id), None)\n    .await?;\nanyhow::ensure!(\n    desc.shards.iter().any(|s| s.tenant_shard_id == *tenant_shard_id),\n    \"shard {} not present; available shards: {:?}\",\n    tenant_shard_id,\n    desc.shards.iter().map(|s| s.tenant_shard_id.to_string()).collect::<Vec<_>>()\n);","typeGuard":"fn shard_exists(desc: &TenantDescribeResponse, id: &TenantShardId) -> bool {\n    desc.shards.iter().any(|s| s.tenant_shard_id == *id)\n}","tryCatchPattern":null,"preventionTips":["Always resolve shard ids from a fresh tenant describe rather than caching them across resharding events","Remember unsharded tenants expose exactly one shard (number 0)","Re-list shards after splits/merges before watching or migrating"],"tags":["storcon","tenant-shard","not-found","cli"],"backgroundTag":"resource-not-found","analyzedSha":"8f60b04da47ffefe0e52bda2440134b42874eb75","analyzedAt":"2026-08-16T23:39:28.135Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}