dotnet/orleans · error · InvalidOperationException
Azure Table journal row "{entity.RowKey}" contains a non-con
Error message
Azure Table journal row "{entity.RowKey}" contains a non-contiguous binary property "{propertyName}". What it means
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.
Source
Thrown at src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs:911
TableEntity entity,
ArcBufferWriter buffer,
IJournalStorageConsumer consumer,
IJournalMetadata metadata)
{
var length = 0L;
var foundChunk = false;
var foundGap = false;
foreach (var propertyName in ChunkPropertyNames)
{
if (!entity.TryGetValue(propertyName, out var value))
{
foundGap = true;
continue;
}
if (foundGap)
{
throw new InvalidOperationException(
$"Azure Table journal row \"{entity.RowKey}\" contains a non-contiguous binary property \"{propertyName}\".");
}
ReadOnlyMemory<byte> chunk = value switch
{
byte[] bytes => bytes,
BinaryData binaryData => binaryData.ToMemory(),
_ => throw new InvalidOperationException(
$"Azure Table journal row \"{entity.RowKey}\" property \"{propertyName}\" is not a binary value."),
};
if (chunk.IsEmpty)
{
throw new InvalidOperationException(
$"Azure Table journal row \"{entity.RowKey}\" property \"{propertyName}\" is empty.");
}
foundChunk = true;View on GitHub (pinned to fca799fa70)
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.
Defensive patterns
Strategy: try-catch
Try / catch
try { await journalStorage.ReadAsync(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("non-contiguous binary property"))
{
// Log RowKey, quarantine the partition, and trigger a journal Replace to rebuild.
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Azure Table journal row "{entity.RowKey}" property "{propert
- Azure Table journal row "{entity.RowKey}" property "{propert
- Azure Table journal row "{entity.RowKey}" does not contain j
- Azure Table journal header is missing its generation propert
- Azure Table journal header count or length properties are in
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/b6d46af20d6072d7.
Report an issue: GitHub.