dotnet/orleans · critical · InvalidOperationException
Storage state corrupted: no record for committed state v{thi
Error message
Storage state corrupted: no record for committed state v{this.key.CommittedSequenceId} What it means
Thrown during DynamoDBTransactionalStateStorage.Load when key.CommittedSequenceId is non-zero but no matching state record exists in the loaded states list (FindState returns false). This indicates the persisted metadata points at a committed version that has no corresponding row, i.e., the transaction state table is inconsistent/corrupted for this partition. The provider logs a critical partition error before throwing InvalidOperationException.
Source
Thrown at src/AWS/Orleans.Transactions.DynamoDB/TransactionalState/DynamoDBTransactionalStateStorage.cs:89
LogDebugLoadedV0Fresh(this.partitionKey);
this.requiresReload = false;
// first time load
return new TransactionalStorageLoadResponse<TState>();
}
TState committedState;
if (this.key.CommittedSequenceId == 0)
{
committedState = new TState();
}
else
{
if (!this.FindState(this.key.CommittedSequenceId, out var pos))
{
var error = $"Storage state corrupted: no record for committed state v{this.key.CommittedSequenceId}";
LogCriticalPartitionError(this.partitionKey, error);
throw new InvalidOperationException(error);
}
committedState = this.ConvertFromStorageFormat<TState>(states[pos].Value);
}
var PrepareRecordsToRecover = new List<PendingTransactionState<TState>>();
for (int i = 0; i < states.Count; i++)
{
var kvp = states[i];
// pending states for already committed transactions can be ignored
if (kvp.Key <= key.CommittedSequenceId)
continue;
// upon recovery, local non-committed transactions are considered aborted
if (kvp.Value.TransactionManager is null or { Length: 0 })
break;
View on GitHub (pinned to fca799fa70)
Solutions
- Restore the missing state row(s) for the committed sequence id from a consistent backup.
- If recovery is impossible, reset/clear the affected grain's transaction state (accept data loss) and let it reinitialize from v0.
- Stop all out-of-band processes that mutate the Orleans transaction state table.
- Verify backups are taken with DynamoDB point-in-time or on-demand backups that preserve cross-row consistency.
- File/examine an Orleans issue if this occurs without external tampering on a supported version.
Defensive patterns
Strategy: try-catch
Try / catch
try { var resp = await store.Load(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Storage state corrupted"))
{
logger.LogCritical(ex, "Transaction state for partition {Key} is corrupted.", partitionKey);
// escalate: quarantine the grain / restore from backup / reset state
throw;
} Prevention
- Never mutate the Orleans transaction state table out-of-band.
- Use DynamoDB point-in-time backups for cross-row consistency.
- Validate table integrity after any cross-version migration.
- Stop external tools from writing to the storage table.
When it happens
Trigger: Manual deletion or truncation of rows in the transaction state DynamoDB table; partial writes that committed metadata without the associated state entity; a failed/aborted migration; schema/version drift where older rows are missing; bugs in an upstream transaction layer leaving dangling CommittedSequenceId.
Common situations: Operator deleted DynamoDB items outside Orleans; table restored from a non-transactionally-consistent backup/point-in-time that split metadata and state rows; cross-version upgrade where the storage format changed and old rows were dropped; concurrent tools writing to the same table.
Related errors
- The transactional state storage provider name is required.
- Configuration for DynamoDBTransactionalStateStorage {this.na
- Configuration for DynamoDBTransactionalStateStorage {this.na
- Configuration for DynamoDBTransactionalStateStorage {this.na
- Load must be called after a failed Store before this storage
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/f42978bc2a606ee8.
Report an issue: GitHub.