{"record":{"id":"3da05fa5913107e5","repo":"dotnet/orleans","slug":"the-membership-table-does-not-contain-a-version-ro","errorCode":null,"errorMessage":"The membership table does not contain a version row.","messagePattern":"The membership table does not contain a version row\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Azure/Orleans.Clustering.AzureStorage/AzureBasedMembershipTable.cs","lineNumber":202,"sourceCode":"                        continue;\n                    }\n                    else\n                    {\n                        try\n                        {\n\n                            MembershipEntry membershipEntry = Parse(tableEntry);\n                            memEntries.Add(new Tuple<MembershipEntry, string>(membershipEntry, tuple.ETag));\n                        }\n                        catch (Exception exc)\n                        {\n                            LogErrorParsingMembershipTableDataIgnoring(exc, tableEntry);\n                        }\n                    }\n                }\n                var data = new MembershipTableData(\n                    memEntries,\n                    tableVersion ?? throw new InvalidOperationException(\"The membership table does not contain a version row.\"));\n                return data;\n            }\n            catch (Exception exc)\n            {\n                LogErrorParsingMembershipTableData(exc, new(entries));\n                throw;\n            }\n        }\n\n        private static MembershipEntry Parse(SiloInstanceTableEntry tableEntry)\n        {\n            var parse = new MembershipEntry\n            {\n                HostName = tableEntry.HostName!,\n                Status = (SiloStatus)Enum.Parse(typeof(SiloStatus), tableEntry.Status!)\n            };\n\n            if (!string.IsNullOrEmpty(tableEntry.ProxyPort))","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/Azure/Orleans.Clustering.AzureStorage/AzureBasedMembershipTable.cs#L184-L220","documentation":"Thrown by AzureBasedMembershipTable.Convert when, after iterating all entries, no table version row was found (tableVersion stayed null). Orleans requires exactly one version row per partition to coordinate membership updates; its absence means the table is uninitialized or the version row was deleted. InvalidOperationException is thrown and the outer catch logs via LogErrorParsingMembershipTableData.","triggerScenarios":"Reading membership when the partition contains silo rows but no TABLE_VERSION_ROW. Happens if the version row was manually removed, a cleanup deleted it, or table initialization failed partway.","commonSituations":"Manual deletion of the version row in Azure Storage Explorer; a buggy cleanup agent that removed boundary/version rows; partial init where silos registered but the version row insert failed; schema drift between Orleans versions.","solutions":["Recreate the version row: insert an entity with PartitionKey=<deploymentId>, RowKey='Version', MembershipVersion='0' (or the current max), then restart silos.","If acceptable, delete the whole partition and let Orleans reinitialize the membership table.","Upgrade all silos to a consistent Orleans version so version-row creation logic agrees.","Audit cleanup/management code for any path that could delete the version row."],"exampleFix":"// via Azure Data Table SDK\nvar versionRow = new TableEntity(deploymentId, \"Version\") {\n    [\"MembershipVersion\"] = \"0\"\n};\nawait tableClient.UpsertEntityAsync(versionRow);","handlingStrategy":"try-catch","validationCode":"// after reading entries, verify a version row exists before consuming:\nbool hasVersion = entries.Any(e => e.Entity.RowKey == \"Version\");\nif (!hasVersion) throw new InvalidOperationException(\"Recreate the Version row.\");","typeGuard":null,"tryCatchPattern":"try { var data = await membershipTable.ReadMembershipTableAsync(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"does not contain a version row\"))\n{ /* recreate Version row with MembershipVersion=0 and retry */ }","preventionTips":["Audit cleanup/migration code so it never deletes the Version row.","Keep all silos on the same Orleans version.","If the table is corrupt, delete the partition and reinitialize rather than patching."],"tags":["csharp","dotnet","orleans","azure-storage","membership","data-corruption"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}