dotnet/orleans · critical · KeyNotFoundException

Could not find cluster version entry for {this._partitionId}

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.

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)

Solutions

  1. Ensure the first silo in the cluster calls InitializeMembershipTable(tryInitTableVersion: true) so TryCreateTableVersionEntry creates the version doc.
  2. Verify FirestoreOptions (project id, collection prefix, emulator vs. production) point to the same collection where the cluster version should live.
  3. If the version doc was deleted, re-initialize the membership table (or let a silo recreate it) before issuing read requests.
  4. 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

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


AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13). Data as JSON: /api/errors/05f2396a21720d60. Report an issue: GitHub.