dotnet/orleans · critical · InvalidOperationException

The table version row does not contain a membership version.

Error message

The table version row does not contain a membership version.

What it means

Thrown by AzureBasedMembershipTable.Convert while parsing the table version row: the row whose RowKey equals TABLE_VERSION_ROW had a null MembershipVersion. Orleans uses this numeric version for optimistic concurrency on membership updates; a null means the row is corrupt or was written by an incompatible version. InvalidOperationException surfaces during a membership table read.

Source

Thrown at src/Azure/Orleans.Clustering.AzureStorage/AzureBasedMembershipTable.cs:177

                    entry,
                    tableManager.TableName);
                throw;
            }
        }

        private MembershipTableData Convert(List<(SiloInstanceTableEntry Entity, string ETag)> entries)
        {
            try
            {
                var memEntries = new List<Tuple<MembershipEntry, string>>(Math.Max(0, entries.Count - 1));
                TableVersion? tableVersion = null;
                foreach (var tuple in entries)
                {
                    var tableEntry = tuple.Entity;
                    if (tableEntry.RowKey.Equals(SiloInstanceTableEntry.TABLE_VERSION_ROW))
                    {
                        var membershipVersion = tableEntry.MembershipVersion
                            ?? throw new InvalidOperationException("The table version row does not contain a membership version.");
                        tableVersion = new TableVersion(
                            int.Parse(membershipVersion, CultureInfo.InvariantCulture),
                            tuple.ETag);
                    }
                    else if (SiloInstanceTableEntry.IsVersionRow(tableEntry.RowKey))
                    {
                        continue;
                    }
                    else
                    {
                        try
                        {

                            MembershipEntry membershipEntry = Parse(tableEntry);
                            memEntries.Add(new Tuple<MembershipEntry, string>(membershipEntry, tuple.ETag));
                        }
                        catch (Exception exc)
                        {

View on GitHub (pinned to fca799fa70)

Solutions

  1. Inspect the TABLE_VERSION_ROW entity in Azure Table Storage and restore a numeric MembershipVersion value.
  2. If the cluster is fresh and the table is corrupt, delete the partition and let Orleans reinitialize membership (data loss for membership only).
  3. Ensure all silos run a compatible Orleans version that writes MembershipVersion on the version row.
  4. Avoid editing membership table entities by hand; use the Orleans management APIs.

Example fix

// remediation (Azure Storage Explorer / az CLI)
// Locate the entity: PartitionKey=<deploymentId>, RowKey='Version'
// Set MembershipVersion to the last known version (e.g. '0' or the max SiloMembershipVersion)

// after the row is repaired, restart a silo to trigger a fresh membership read
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check before acting on membership data is not practical; validate on read:
var version = versionRow.MembershipVersion;
if (string.IsNullOrWhiteSpace(version))
    throw new InvalidOperationException("Version row missing MembershipVersion; repair in Azure Table.");

Try / catch

try { var data = await membershipTable.ReadMembershipTableAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("table version row does not contain a membership version"))
{ /* repair the version row, then retry */ }

Prevention

When it happens

Trigger: Reading the membership table (ReadAll/CleanupDefunct/Merge) when the version row exists in Azure Table Storage but its MembershipVersion property is empty/null. The exception is wrapped by the outer catch and re-logged via LogErrorParsingMembershipTableData.

Common situations: Corrupted membership table row (manual edits, partial writes, storage emulator bugs); rolling upgrade where a newer Orleans writes a schema the older code cannot read; a version row created by an external tool missing the MembershipVersion field; Azure table entity property dropped by a migration.

Related errors


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