dotnet/orleans · error · KeyNotFoundException
Did not read table version row. Read = {0}
Error message
Did not read table version row. Read = {0} What it means
Thrown by OrleansSiloInstanceManager.FindSiloEntryAndTableVersionRow when the query returned 1-2 rows but none of them is the TABLE_VERSION_ROW. This is distinct from error 154 (no version row at all across the whole partition): here the targeted query came back without a version row, indicating the version row is missing or was not matched. KeyNotFoundException lists what was read.
Source
Thrown at src/Azure/Orleans.Clustering.AzureStorage/OrleansSiloInstanceManager.cs:265
{
string rowKey = SiloInstanceTableEntry.ConstructRowKey(siloAddress);
var filter = TableClient.CreateQueryFilter($"(PartitionKey eq {DeploymentId}) and ((RowKey eq {rowKey}) or (RowKey eq {SiloInstanceTableEntry.TABLE_VERSION_ROW}))");
var queryResults = await storage.ReadTableEntriesAndEtagsAsync(filter);
if (queryResults.Count < 1 || queryResults.Count > 2)
throw new KeyNotFoundException(string.Format("Could not find table version row or found too many entries. Was looking for key {0}, found = {1}", siloAddress, Utils.EnumerableToString(queryResults)));
var numTableVersionRows = 0;
foreach (var entry in queryResults)
{
if (entry.Item1.RowKey == SiloInstanceTableEntry.TABLE_VERSION_ROW)
{
numTableVersionRows++;
}
}
if (numTableVersionRows < 1)
throw new KeyNotFoundException(string.Format("Did not read table version row. Read = {0}", Utils.EnumerableToString(queryResults)));
if (numTableVersionRows > 1)
throw new KeyNotFoundException(string.Format("Read {0} table version rows, while was expecting only 1. Read = {1}", numTableVersionRows, Utils.EnumerableToString(queryResults)));
return queryResults;
}
internal async Task<List<(SiloInstanceTableEntry Entity, string ETag)>> FindAllSiloEntries(
CancellationToken cancellationToken = default)
{
MembershipTableQueryResult query = default;
for (var attempt = 0; attempt < MaxMembershipSnapshotAttempts; attempt++)
{
query = await membershipTableReadStorage.ReadAllTableEntriesForPartitionAsync(DeploymentId, cancellationToken);
var tableVersion = ValidateAllSiloEntries(query.Entries);
if (CanAcceptSnapshot(query, tableVersion))
{
return RemoveBoundaryVersionRows(query.Entries);View on GitHub (pinned to fca799fa70)
Solutions
- Recreate the version row (PartitionKey=DeploymentId, RowKey=Version, MembershipVersion=<current>) and retry.
- If the cluster is being initialized, ensure CreateTableVersionEntry runs at startup before silos query.
- Audit for any cleanup or migration code that could remove the version row.
- Run all silos on the same Orleans version so the version-row RowKey is consistent.
Example fix
// remediation
var versionRow = new TableEntity(deploymentId, "Version") { ["MembershipVersion"] = currentVersion.ToString() };
await tableClient.UpsertEntityAsync(versionRow);
// then retry FindSiloEntryAndTableVersionRow Defensive patterns
Strategy: try-catch
Validate before calling
// verify the version row exists in the partition before targeted silo reads:
var any = await manager.FindAllSiloEntries();
bool hasVersion = any.Any(e => e.Entity.RowKey == SiloInstanceTableEntry.TABLE_VERSION_ROW);
if (!hasVersion) { /* recreate Version row */ } Try / catch
try { var rows = await manager.FindSiloEntryAndTableVersionRow(addr); }
catch (KeyNotFoundException ex) when (ex.Message.Contains("Did not read table version row"))
{ /* recreate Version row and retry */ } Prevention
- Ensure version-row creation runs at silo startup before queries.
- Audit cleanup code so it never deletes the Version row.
- Run a consistent Orleans version across the cluster.
When it happens
Trigger: The silo row was found but the version row was absent from the 1-2 returned entities. Happens when the version row was deleted, not yet created, or the RowKey comparison fails due to casing/encoding.
Common situations: Version row manually removed; partial init where the silo registered before the version row insert; mixed Orleans versions with different version-row RowKey conventions; the partition was migrated and the version row dropped.
Related errors
- The table version row does not contain a membership version.
- The membership table does not contain a version row.
- SuspectingSilos.Length of {0} as read from Azure table is no
- Could not find table version row or found too many entries.
- The table version entry must have a membership version.
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/9d02e8c7f1f956e1.
Report an issue: GitHub.