{"record":{"id":"f880997f142d9fdb","repo":"abpframework/abp","slug":"the-content-is-too-large-for-the-encrypted-blob-fo","errorCode":null,"errorMessage":"The content is too large for the encrypted BLOB format (chunk index overflow)!","messagePattern":"The content is too large for the encrypted BLOB format \\(chunk index overflow\\)!","errorType":"exception","errorClass":"AbpException","httpStatus":null,"severity":"critical","filePath":"framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobEncryptionCodec.cs","lineNumber":650,"sourceCode":"        // Both are required: without Position the remaining length is unknown (the stream\n        // may already be partially consumed), and guessing it would report a wrong\n        // ciphertext length and cause a short write on length-strict providers.\n        try\n        {\n            var plainLength = plainStream.Length - plainStream.Position;\n            if (plainLength < 0)\n            {\n                return null;\n            }\n\n            var fullChunkCount = plainLength / chunkSize;\n            var chunkRecordCount = fullChunkCount + (plainLength % chunkSize > 0 ? 1 : 0) + 1; // +1: terminal record\n\n            // The chunk index (including the terminal record) is a 32-bit value; fail\n            // before any output instead of after writing terabytes of ciphertext\n            if (chunkRecordCount - 1 > int.MaxValue)\n            {\n                throw new AbpException(\"The content is too large for the encrypted BLOB format (chunk index overflow)!\");\n            }\n\n            checked\n            {\n                return Magic.Length + 1L + HeaderSize + plainLength +\n                       chunkRecordCount * (ChunkLengthPrefixSize + GcmTagSize);\n            }\n        }\n        catch (Exception ex) when (ex is NotSupportedException || ex is IOException)\n        {\n            // The length is optional; a probe failure must not fail the save\n            return null;\n        }\n        catch (OverflowException)\n        {\n            return null;\n        }\n    }","sourceCodeStart":632,"sourceCodeEnd":668,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobEncryptionCodec.cs#L632-L668","documentation":"TryCalculateEncryptedLength projects the ciphertext size from the plaintext length. The chunk index (including the terminal record) is a 32-bit value, so if chunkRecordCount - 1 would exceed int.MaxValue the codec throws up front — before writing terabytes of unusable ciphertext — rather than failing mid-stream.","triggerScenarios":"Saving a stream whose Length/Position imply a plaintext that requires more than int.MaxValue chunk records (content/chunkSize > 2^31) given the configured chunk size.","commonSituations":"Tiny chunkSize configured against very large content; an accidental huge input stream; misconfigured chunkSize default.","solutions":["Increase the configured chunk size so the content fits within int.MaxValue chunks.","Split the content into multiple BLOBs each under the limit.","Enforce a content-size ceiling at the application layer (chunkSize * int.MaxValue).","Audit and correct chunkSize — it should be multi-MB, not KB."],"exampleFix":"// before\nConfigure<AbpBlobStoringEncryptionOptions>(o => o.ChunkSize = 16 * 1024);\nawait blob.SaveAsync(\"huge\", giantStream); // throws [91]\n\n// after\nConfigure<AbpBlobStoringEncryptionOptions>(o => o.ChunkSize = 8 * 1024 * 1024);\n// or split 'giantStream' into multiple blobs below the ceiling","handlingStrategy":"validation","validationCode":"// Reject content too large to fit the 32-bit chunk-index space.\nstatic void AssertFitsEncryptedFormat(long contentLength, int chunkSize)\n{\n    var chunkRecords = contentLength / chunkSize\n        + (contentLength % chunkSize > 0 ? 1 : 0) + 1;\n    if (chunkRecords - 1 > int.MaxValue)\n        throw new InvalidOperationException(\n            $\"Content ({contentLength} B) exceeds the encrypted format limit for chunkSize={chunkSize}.\");\n}","typeGuard":"public sealed record ChunkSize(int Value)\n{\n    public ChunkSize(int bytes)\n    {\n        if (bytes is < 1024 or > 64 * 1024 * 1024)\n            throw new ArgumentOutOfRangeException(nameof(bytes));\n        Value = bytes;\n    }\n}","tryCatchPattern":"try\n{\n    await blob.SaveAsync(name, bigStream);\n}\ncatch (AbpException ex) when (ex.Message.Contains(\"chunk index overflow\"))\n{\n    logger.LogError(ex, \"Content too large for the encrypted format; raise ChunkSize or split.\");\n    throw;\n}","preventionTips":["Use a multi-MB ChunkSize.","Pre-check content length against chunkSize * int.MaxValue at the API boundary.","Split very large content into multiple BLOBs.","Review chunkSize during configuration audits."],"tags":["crypto","capacity","nonce","chunk-index"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}