{"record":{"id":"b6d46af20d6072d7","repo":"dotnet/orleans","slug":"azure-table-journal-row-entity-rowkey-contains","errorCode":null,"errorMessage":"Azure Table journal row \"{entity.RowKey}\" contains a non-contiguous binary property \"{propertyName}\".","messagePattern":"Azure Table journal row \"(.+?)\" contains a non-contiguous binary property \"(.+?)\"\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs","lineNumber":911,"sourceCode":"        TableEntity entity,\n        ArcBufferWriter buffer,\n        IJournalStorageConsumer consumer,\n        IJournalMetadata metadata)\n    {\n        var length = 0L;\n        var foundChunk = false;\n        var foundGap = false;\n        foreach (var propertyName in ChunkPropertyNames)\n        {\n            if (!entity.TryGetValue(propertyName, out var value))\n            {\n                foundGap = true;\n                continue;\n            }\n\n            if (foundGap)\n            {\n                throw new InvalidOperationException(\n                    $\"Azure Table journal row \\\"{entity.RowKey}\\\" contains a non-contiguous binary property \\\"{propertyName}\\\".\");\n            }\n\n            ReadOnlyMemory<byte> chunk = value switch\n            {\n                byte[] bytes => bytes,\n                BinaryData binaryData => binaryData.ToMemory(),\n                _ => throw new InvalidOperationException(\n                    $\"Azure Table journal row \\\"{entity.RowKey}\\\" property \\\"{propertyName}\\\" is not a binary value.\"),\n            };\n\n            if (chunk.IsEmpty)\n            {\n                throw new InvalidOperationException(\n                    $\"Azure Table journal row \\\"{entity.RowKey}\\\" property \\\"{propertyName}\\\" is empty.\");\n            }\n\n            foundChunk = true;","sourceCodeStart":893,"sourceCodeEnd":929,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs#L893-L929","documentation":"A journal data row in Azure Table storage was read with a gap in its chunk sequence: one of the Data00..Data14 properties was missing while a later-numbered property was present. ReadChunks (AzureTableJournalStorage.cs:892) requires chunks to be contiguous from Data00 onward, so a hole means the row is structurally invalid and cannot be safely replayed. The writer (AzureTableJournalStorage.cs:868) never produces gaps, so this points to external modification or partial/corrupted writes.","triggerScenarios":"Returned by ReadChunks when, while iterating ChunkPropertyNames in order, entity.TryGetValue returns false for some DataNN (setting foundGap) and then returns true for a later DataMM. Triggered on any Read/ReadAsync against a row whose data was truncated or hand-edited in the table.","commonSituations":"An operator or migration script deleted a single DataNN property from a row; a partial transaction left some chunk properties unwritten; a different/older writer version that used a different chunk layout co-exists in the same table; tools like Storage Explorer were used to edit entities.","solutions":["Identify and remove/replace the corrupted row(s) in the journal partition (the RowKey in the message tells you which one), then let the journaling layer rebuild via a Replace.","Ensure no external process or alternate code path writes DataNN properties into the journal table — only AzureTableJournalStorage should mutate these rows.","If migrating from a legacy schema, run a clean Replace to publish a fresh generation rather than partially patching existing rows.","Inspect the partition in Storage Explorer for rows where the set of DataNN keys is non-contiguous."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await journalStorage.ReadAsync(...); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"non-contiguous binary property\"))\n{\n    // Log RowKey, quarantine the partition, and trigger a journal Replace to rebuild.\n}","preventionTips":["Allow only AzureTableJournalStorage to write DataNN properties.","Monitor the journal table for schema drift (rows with unexpected property sets).","Never edit journal entities in Storage Explorer."],"tags":["azure-table","data-corruption","journal","chunks"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}