{"record":{"id":"2e22f3ae0b58db68","repo":"dotnet/orleans","slug":"data-too-large-to-write-to-azure-table-size-0-m","errorCode":null,"errorMessage":"Data too large to write to Azure table. Size={0} MaxSize={1}","messagePattern":"Data too large to write to Azure table\\. Size=(.+?) MaxSize=(.+?)","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Azure/Orleans.Persistence.AzureStorage/Providers/Storage/AzureTableStorage.cs","lineNumber":218,"sourceCode":"            else\n            {\n                var properties = SplitBinaryData(binaryData);\n\n                foreach (var keyValuePair in properties.Zip(GetPropertyNames(BINARY_DATA_PROPERTY_NAME),\n                (property, name) => new KeyValuePair<string, object>(name, property.ToArray())))\n                {\n                    entity[keyValuePair.Key] = keyValuePair.Value;\n                }\n            }\n        }\n\n        private void CheckMaxDataSize(int dataSize, int maxDataSize)\n        {\n            if (dataSize > maxDataSize)\n            {\n                var msg = string.Format(\"Data too large to write to Azure table. Size={0} MaxSize={1}\", dataSize, maxDataSize);\n                LogErrorDataTooLarge(dataSize, maxDataSize);\n                throw new ArgumentOutOfRangeException(\"GrainState.Size\", msg);\n            }\n        }\n\n        private static IEnumerable<ReadOnlyMemory<char>> SplitStringData(ReadOnlyMemory<char> stringData)\n        {\n            var startIndex = 0;\n            while (startIndex < stringData.Length)\n            {\n                var chunkSize = Math.Min(MAX_STRING_PROPERTY_LENGTH, stringData.Length - startIndex);\n\n                yield return stringData.Slice(startIndex, chunkSize);\n\n                startIndex += chunkSize;\n            }\n        }\n\n        private static IEnumerable<ReadOnlyMemory<byte>> SplitBinaryData(ReadOnlyMemory<byte> binaryData)\n        {","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/Azure/Orleans.Persistence.AzureStorage/Providers/Storage/AzureTableStorage.cs#L200-L236","documentation":"Thrown by CheckMaxDataSize when the serialized grain state exceeds the maximum allowed size for an Azure Table entity. Azure Table entities have a 1 MB total limit; Orleans splits data into chunks of MAX_STRING_PROPERTY_LENGTH (32 KB) with MAX_DATA_CHUNKS_COUNT (15), giving approximately 480 KB for string data plus binary data. When dataSize exceeds maxDataSize, an ArgumentOutOfRangeException is thrown.","triggerScenarios":"A grain state object serializes to a payload larger than the configured maxDataSize (derived from chunk size * chunk count). This is checked in ConvertToStorageFormat before attempting the write to Azure Table.","commonSituations":"Grain state contains large collections, embedded files, images, or deeply nested objects. Accumulating unbounded data in grain state (e.g., a shopping cart or log buffer that grows without eviction). Changing a grain's state schema to include large fields. Using Azure Table Storage for data that belongs in Blob Storage.","solutions":["Move large state to Azure Blob Storage (use AddAzureBlobGrainStorage instead of AddAzureTableGrainStorage).","Split the grain into smaller grains with partitioned state.","Evict or compress data in grain state before it grows too large.","Store large binary payloads externally (Blob Storage) and keep only a reference/URI in grain state."],"exampleFix":"// before: large grain state in table storage\n[StorageProvider(ProviderName = \"tableStore\")]\npublic class BigGrain : Grain, IBigGrain\n{\n    private List<byte[]> _largeData; // exceeds table limits\n}\n\n// after: use blob storage for large state\n[StorageProvider(ProviderName = \"blobStore\")]\npublic class BigGrain : Grain, IBigGrain { }","handlingStrategy":"validation","validationCode":"// Before writing, check serialized state size\nvar serialized = storageSerializer.Serialize(grainState.State);\nif (serialized.Length > 480 * 1024) // approx table limit\n    throw new InvalidOperationException($\"Grain state too large ({serialized.Length} bytes) for Azure Table Storage. Use Blob Storage.\");","typeGuard":null,"tryCatchPattern":"try { await grain.WriteStateAsync(); }\ncatch (ArgumentOutOfRangeException ex) when (ex.Message.Contains(\"Data too large\"))\n{\n    logger.LogError(ex, \"Grain state exceeds Azure Table size limit — move to Blob Storage.\");\n    throw;\n}","preventionTips":["Monitor grain state size and enforce an application-level limit before it hits the storage limit.","Design grain state to be compact — store references to large blobs instead of inline data.","Use Azure Blob Storage for grains with large state.","Implement eviction/compression for growing collections in grain state."],"tags":["azure","table-storage","data-size","serialization","limits","orleans"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}