dotnet/orleans · critical · KeyNotFoundException
Could not find cluster version entry for
Error message
Could not find cluster version entry for {this._partitionId} What it means
KeyNotFoundException from FirestoreMembershipTable.ReadRow when the cluster-version document (identified by the sanitized ClusterId, _partitionId) does not exist in the Firestore collection at read time. Membership reads require the version entry to exist; its absence means the membership table was never initialized (TryCreateTableVersionEntry did not run or did not persist). The throw happens inside the transaction after both snapshots are fetched.
Solutions
- Ensure the first silo in the cluster calls InitializeMembershipTable(tryInitTableVersion: true) so TryCreateTableVersionEntry creates the version doc.
- Verify FirestoreOptions (project id, collection prefix, emulator vs. production) point to the same collection where the cluster version should live.
- If the version doc was deleted, re-initialize the membership table (or let a silo recreate it) before issuing read requests.
- Confirm the ClusterId used by all silos matches; _partitionId is Utils.SanitizeId(ClusterId), so a mismatched ClusterId yields a different version doc.
Example fix
// before var membership = host.Services.GetRequiredService<IMembershipTable>(); await membership.ReadRow(siloAddr); // throws if version doc absent // after var membership = host.Services.GetRequiredService<IMembershipTable>(); await membership.InitializeMembershipTable(tryInitTableVersion: true); // ensures version doc exists await membership.ReadRow(siloAddr);
Defensive patterns
Strategy: validation
Validate before calling
await membership.InitializeMembershipTable(tryInitTableVersion: true); // verify FirestoreOptions point to the intended project/collection // and that ClusterId is consistent across all silos await membership.ReadRow(key);
Try / catch
try { await membership.ReadRow(key); }
catch (KeyNotFoundException ex) when (ex.Message.Contains("cluster version entry"))
{ logger.LogCritical(ex, "Membership version doc missing; reinitialize the table"); throw; } Prevention
- Ensure the first silo initializes with tryInitTableVersion: true
- Keep FirestoreOptions (project/collection) consistent across silos
- Do not manually delete the cluster version document
When it happens
Trigger: ReadRow(key) executes a transaction; the versionSnapshot for collection.Document(_partitionId).Exists is false. This occurs when InitializeMembershipTable was called with tryInitTableVersion=false, when the version doc was deleted, or when the Firestore project/collection points to a different deployment than where the cluster version was created.
Common situations: A fresh Firestore collection with no version doc and a silo that did not (or could not) create one; a split-brain where two silos target different Firestore projects/keyspaces; accidental deletion of the cluster version document; or reading membership before the first silo has initialized the version entry.
Related errors
- Session created from configuration…
- Cluster id does not match CassandraClusteringTable value of…
- Invalid values for . is required.
- Invalid values for . Configure exactly one of or .
- Session created from configuration…
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/05f2396a21720d60.
Report an issue: GitHub.
Appendix: source
Thrown at src/Google/Orleans.Clustering.Firestore/FirestoreMembershipTable.cs:87
.Chunk(FirestoreDataManager.MaxBatchSize)
.Select(chunk => this._storage.DeleteEntities(chunk)));
}
public async Task<MembershipTableData> ReadRow(SiloAddress key)
{
try
{
var collection = this._storage.GetCollection();
var data = await this._storage.ExecuteTransaction(async transaction =>
{
var versionSnapshot = await transaction.GetSnapshotAsync(
collection.Document(this._partitionId),
transaction.CancellationToken);
var siloSnapshot = await transaction.GetSnapshotAsync(
collection.Document(key.ToParsableString()),
transaction.CancellationToken);
if (!versionSnapshot.Exists)
throw new KeyNotFoundException($"Could not find cluster version entry for {this._partitionId}");
var silos = siloSnapshot.Exists
? new[] { siloSnapshot.ConvertTo<SiloInstanceEntity>() }
: Array.Empty<SiloInstanceEntity>();
return (silos, versionSnapshot.ConvertTo<ClusterVersionEntity>());
});
var table = Convert(data);
LogReadEntry(key, table);
return table;
}
catch (Exception exc)
{
LogReadEntryError(exc, key);
throw;
}View on GitHub (pinned to fca799fa70)