dotnet/orleans · error · InconsistentStateException

Azure Table transactional state storage conflict. Partition=

Error message

Azure Table transactional state storage conflict. Partition={key.PartitionKey} ActionIndex={actionIndexText} ActionType={actionType} RowKey={rowKey} HttpStatus={requestFailedException.Status} ErrorCode={errorCode} FailedOperationIndex={failedOperationIndexText}

What it means

Thrown by AzureTableTransactionalStateStorage when a batch table operation fails with an HTTP conflict (e.g. 412 Precondition Failed / 409) during a Store. The error is surfaced as InconsistentStateException carrying partition, action index/type, row key, HTTP status, and error code for diagnostics.

Source

Thrown at src/Azure/Orleans.Transactions.AzureStorage/TransactionalState/AzureTableTransactionalStateStorage.cs:486

                                    i,
                                    batchOperation[i].ActionType,
                                    requestFailedException.Status,
                                    errorCode,
                                    failedOperationIndexText);
                            }
                        }

                        LogErrorTransactionalStateStoreConflict(
                            logger,
                            key.PartitionKey,
                            actionIndexText,
                            actionType,
                            rowKey,
                            requestFailedException.Status,
                            errorCode,
                            failedOperationIndexText);

                        throw new InconsistentStateException(
                            $"Azure Table transactional state storage conflict. Partition={key.PartitionKey} ActionIndex={actionIndexText} ActionType={actionType} RowKey={rowKey} HttpStatus={requestFailedException.Status} ErrorCode={errorCode} FailedOperationIndex={failedOperationIndexText}",
                            "Unknown",
                            key.ETag.ToString());
                    }
                    catch (Exception ex)
                    {
                        if (logger.IsEnabled(LogLevel.Trace))
                        {
                            for (int i = 0; i < batchOperation.Count; i++)
                            {
                                LogTraceBatchOpFailed(
                                    logger,
                                    batchOperation[i].Entity.PartitionKey,
                                    batchOperation[i].Entity.RowKey,
                                    i,
                                    batchOperation[i].ActionType,
                                    ex is RequestFailedException requestFailedException ? requestFailedException.Status : 0,
                                    ex is RequestFailedException { ErrorCode: { } errorCode } ? errorCode : "Unavailable",

View on GitHub (pinned to fca799fa70)

Solutions

  1. Retry after re-loading the snapshot to refresh etags.
  2. Inspect the logged Partition/RowKey/HttpStatus/ErrorCode to identify the conflicting entity.
  3. Lower concurrency on the grain or batch size.
  4. Check for Azure Table throttling and apply backoff.
Defensive patterns

Strategy: retry

Try / catch

try { await storage.Store(...); }
catch (InconsistentStateException ex)
{ logger.LogWarning(ex, "conflict on {Partition}"); await Task.Delay(backoff); await storage.Load(); await storage.Store(...); }

Prevention

When it happens

Trigger: An entity batch operation hits an etag precondition failure or storage-level conflict while preparing/committing transactional state.

Common situations: Concurrent writers to the same partition; throttling (429) reclassified as conflict; partial batch where some entities changed.

Related errors


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