{"record":{"id":"9d02e8c7f1f956e1","repo":"dotnet/orleans","slug":"did-not-read-table-version-row-read-0","errorCode":null,"errorMessage":"Did not read table version row. Read = {0}","messagePattern":"Did not read table version row\\. Read = (.+?)","errorType":"exception","errorClass":"KeyNotFoundException","httpStatus":null,"severity":"error","filePath":"src/Azure/Orleans.Clustering.AzureStorage/OrleansSiloInstanceManager.cs","lineNumber":265,"sourceCode":"        {\n            string rowKey = SiloInstanceTableEntry.ConstructRowKey(siloAddress);\n\n            var filter = TableClient.CreateQueryFilter($\"(PartitionKey eq {DeploymentId}) and ((RowKey eq {rowKey}) or (RowKey eq {SiloInstanceTableEntry.TABLE_VERSION_ROW}))\");\n            var queryResults = await storage.ReadTableEntriesAndEtagsAsync(filter);\n            if (queryResults.Count < 1 || queryResults.Count > 2)\n                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)));\n\n            var numTableVersionRows = 0;\n            foreach (var entry in queryResults)\n            {\n                if (entry.Item1.RowKey == SiloInstanceTableEntry.TABLE_VERSION_ROW)\n                {\n                    numTableVersionRows++;\n                }\n            }\n\n            if (numTableVersionRows < 1)\n                throw new KeyNotFoundException(string.Format(\"Did not read table version row. Read = {0}\", Utils.EnumerableToString(queryResults)));\n\n            if (numTableVersionRows > 1)\n                throw new KeyNotFoundException(string.Format(\"Read {0} table version rows, while was expecting only 1. Read = {1}\", numTableVersionRows, Utils.EnumerableToString(queryResults)));\n\n            return queryResults;\n        }\n\n        internal async Task<List<(SiloInstanceTableEntry Entity, string ETag)>> FindAllSiloEntries(\n            CancellationToken cancellationToken = default)\n        {\n            MembershipTableQueryResult query = default;\n            for (var attempt = 0; attempt < MaxMembershipSnapshotAttempts; attempt++)\n            {\n                query = await membershipTableReadStorage.ReadAllTableEntriesForPartitionAsync(DeploymentId, cancellationToken);\n                var tableVersion = ValidateAllSiloEntries(query.Entries);\n                if (CanAcceptSnapshot(query, tableVersion))\n                {\n                    return RemoveBoundaryVersionRows(query.Entries);","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/Azure/Orleans.Clustering.AzureStorage/OrleansSiloInstanceManager.cs#L247-L283","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// remediation\nvar versionRow = new TableEntity(deploymentId, \"Version\") { [\"MembershipVersion\"] = currentVersion.ToString() };\nawait tableClient.UpsertEntityAsync(versionRow);\n// then retry FindSiloEntryAndTableVersionRow","handlingStrategy":"try-catch","validationCode":"// verify the version row exists in the partition before targeted silo reads:\nvar any = await manager.FindAllSiloEntries();\nbool hasVersion = any.Any(e => e.Entity.RowKey == SiloInstanceTableEntry.TABLE_VERSION_ROW);\nif (!hasVersion) { /* recreate Version row */ }","typeGuard":null,"tryCatchPattern":"try { var rows = await manager.FindSiloEntryAndTableVersionRow(addr); }\ncatch (KeyNotFoundException ex) when (ex.Message.Contains(\"Did not read table version row\"))\n{ /* recreate Version row and retry */ }","preventionTips":["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."],"tags":["csharp","dotnet","orleans","azure-storage","membership","not-found","data-corruption"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}