dotnet/orleans · error · ArgumentOutOfRangeException

Data too large to write to DynamoDB table. Size={dataSize} M

Error message

Data too large to write to DynamoDB table. Size={dataSize} MaxSize={MAX_DATA_SIZE}

What it means

Thrown by DynamoDBGrainStorage.ConvertToStorageFormat when the serialized grain state plus the partition/sort/version key sizes exceed MAX_DATA_SIZE (400 * 1024 bytes). DynamoDB has a 400 KB item limit; Orleans reserves room for its own columns and rejects the write with ArgumentOutOfRangeException('GrainState.Size') before it hits the AWS API.

Source

Thrown at src/AWS/Orleans.Persistence.DynamoDB/Provider/DynamoDBGrainStorage.cs:347

        }

        internal void ConvertToStorageFormat(object? grainState, GrainStateRecord entity)
        {
            int dataSize;
            // Convert to binary format
            entity.State = this.options.GrainStorageSerializer.Serialize(grainState).ToArray();
            dataSize = BINARY_STATE_PROPERTY_NAME.Length + entity.State.Length;

            LogTraceWritingBinaryData(logger, dataSize, entity.GrainReference, entity.GrainType);

            var pkSize = GRAIN_REFERENCE_PROPERTY_NAME.Length + entity.GrainReference.Length;
            var rkSize = GRAIN_TYPE_PROPERTY_NAME.Length + entity.GrainType.Length;
            var versionSize = ETAG_PROPERTY_NAME.Length + entity.ETag.ToString().Length;

            if ((pkSize + rkSize + versionSize + dataSize) > MAX_DATA_SIZE)
            {
                var msg = $"Data too large to write to DynamoDB table. Size={dataSize} MaxSize={MAX_DATA_SIZE}";
                throw new ArgumentOutOfRangeException("GrainState.Size", msg);
            }
        }

        private void ResetGrainState<T>(IGrainState<T> grainState)
        {
            grainState.RecordExists = false;
            grainState.ETag = null;
            grainState.State = CreateInstance<T>();
        }

        private T CreateInstance<T>() => _activatorProvider.GetActivator<T>().Create();

        [LoggerMessage(
            Level = LogLevel.Information,
            Message = "AWS DynamoDB Grain Storage {Name} is initializing: {InitMsg}"
        )]
        private static partial void LogInformationInitializingDynamoDBGrainStorage(ILogger logger, string name, string initMsg);

View on GitHub (pinned to fca799fa70)

Solutions

  1. Reduce the grain state size — offload large payloads to blob storage and keep only a reference/URL in grain state.
  2. Configure a more compact GrainStorageSerializer (e.g. compression such as Gzip/Orleans's built-in compression) to shrink dataSize.
  3. Split the grain so each activation holds less state, or shard the data across multiple grains.

Example fix

// before: large payload stored inline in grain state
[GenerateSerializer] public class MyState { [Id(0)] public byte[] Blob { get; set; } }

// after: store the blob externally, keep a reference in state
[GenerateSerializer] public class MyState { [Id(0)] public string BlobUri { get; set; } }
Defensive patterns

Strategy: validation

Validate before calling

// Estimate serialized size before writing grain state
var size = GrainStorageSerializer.Serialize(state).ToArray().Length;
if (size > 380 * 1024) // leave headroom under the 400KB limit
    throw new InvalidOperationException("Grain state too large; offload payload to blob storage.");

Type guard

null

Try / catch

try { await grain.WriteStateAsync(); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "GrainState.Size")
{ /* offload large payload to blob, store reference in state */ }

Prevention

When it happens

Trigger: A grain whose serialized state (after GrainStorageSerializer compression/encoding) plus the GrainReference, GrainType and ETag string lengths exceeds 400KB. The check sums pkSize + rkSize + versionSize + dataSize and compares against the constant.

Common situations: Storing large blobs, lists, or cached payloads in grain state; a state class that grew over time; switching to a less efficient storage serializer; embedding base64 data in state.

Related errors


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