dotnet/orleans · error · InvalidOperationException
Azure Table journal header is missing its generation propert
Error message
Azure Table journal header is missing its generation property.
What it means
The journal header row ($header) is missing its Generation property or it is empty. CreateHeaderState (AzureTableJournalStorage.cs:1008) requires a non-empty Generation because the generation string names the current data-row prefix (FormatRowKey at line 991). A header without it cannot address any data rows, so it is treated as corrupt.
Source
Thrown at src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs:1011
private static string[] CreateChunkPropertyNames()
{
var names = new string[MaxChunksPerEntity];
for (var i = 0; i < names.Length; i++)
{
names[i] = string.Create(CultureInfo.InvariantCulture, $"Data{i:D2}");
}
return names;
}
private HeaderState CreateHeaderState(TableEntity entity)
{
ValidateHeaderJournalId(entity);
var generation = entity.GetString(GenerationPropertyName);
if (generation is not { Length: > 0 })
{
throw new InvalidOperationException("Azure Table journal header is missing its generation property.");
}
var rowCount = entity.GetInt64(RowCountPropertyName);
var length = entity.GetInt64(LengthPropertyName);
if (rowCount is not >= 0 || length is not >= 0)
{
throw new InvalidOperationException("Azure Table journal header count or length properties are invalid.");
}
// Headers written by the original provider schema did not have separate compaction counters.
// Conservatively treat the current generation as uncompacted until the next replacement resets them.
var appendRowCount = entity.GetInt64(AppendRowCountPropertyName) ?? rowCount.Value;
var appendLength = entity.GetInt64(AppendLengthPropertyName) ?? length.Value;
if (appendRowCount < 0 || appendLength < 0)
{
throw new InvalidOperationException("Azure Table journal header count or length properties are invalid.");
}
View on GitHub (pinned to fca799fa70)
Solutions
- Delete the malformed $header row and let the journal reinitialize it on the next append/replace.
- Ensure only AzureTableJournalStorage writes the $header row (it always sets Generation via CreateHeaderFlipPatch at line 958).
- Restore from a known-good backup if the header cannot be regenerated.
Defensive patterns
Strategy: try-catch
Try / catch
try { /* read header */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("missing its generation"))
{
// Delete $header and let the next append recreate it.
} Prevention
- Only the provider should write the $header row.
- Back up the header before migrations.
- Validate header completeness after any migration.
When it happens
Trigger: entity.GetString(GenerationPropertyName) returns null or empty string in CreateHeaderState; thrown at AzureTableJournalStorage.cs:1011 when reading the header during a Read, metadata update, or compaction check.
Common situations: An external edit deleted/blanked the Generation field; a legacy or partially-written header row was committed without all fields; a migration wrote a header row but omitted Generation.
Related errors
- Azure Table journal header count or length properties are in
- Azure Table journal row "{entity.RowKey}" contains a non-con
- 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
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/291b8a96cc70754d.
Report an issue: GitHub.