abpframework/abp · error · AbpException

The encrypted BLOB is corrupted or has an invalid format: in

Error message

The encrypted BLOB is corrupted or has an invalid format: invalid chunk length!

What it means

GetCipherChunkSize decodes the 4-byte prefix as a big-endian int and validates 0 <= size <= maxCipherChunkSize. A negative or oversized value means the prefix does not represent a real chunk length — either the bytes are corrupt/tampered, or the reader's chunkSize differs from the writer's.

Source

Thrown at framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobEncryptionCodec.cs:537

        WriteInt32BigEndian(nonceOrAssociatedData, nonceOrAssociatedData.Length - 4, chunkIndex);
    }

    internal static int GetCipherChunkSize(byte[] lengthPrefix, int maxCipherChunkSize)
    {
        if (lengthPrefix.Length == 0)
        {
            throw new AbpException("The encrypted BLOB is corrupted or has an invalid format: missing terminal record!");
        }

        if (lengthPrefix.Length < ChunkLengthPrefixSize)
        {
            throw new AbpException("The encrypted BLOB is corrupted or has an invalid format: truncated chunk!");
        }

        var cipherChunkSize = ReadInt32BigEndian(lengthPrefix, 0);
        if (cipherChunkSize < 0 || cipherChunkSize > maxCipherChunkSize)
        {
            throw new AbpException("The encrypted BLOB is corrupted or has an invalid format: invalid chunk length!");
        }

        return cipherChunkSize;
    }

    internal static byte[]? ReadExactly(Stream stream, int count)
    {
        var buffer = ReadUpTo(stream, count);
        return buffer.Length == count ? buffer : null;
    }

    internal static byte[] ReadUpTo(Stream stream, int count)
    {
        var buffer = new byte[count];
        var totalReadCount = 0;
        while (totalReadCount < count)
        {
            var readCount = stream.Read(buffer, totalReadCount, count - totalReadCount);

View on GitHub (pinned to 7ed43b1931)

Solutions

  1. Ensure the reader's ChunkSize matches the value used to write the BLOB.
  2. If ChunkSize changed, re-encrypt the affected BLOBs.
  3. Verify object integrity in storage (checksums/ETag) to rule out corruption.
  4. Confirm the BLOB is actually an encrypted container (magic header) before decrypting.

Example fix

// before — reader and writer use different chunk sizes
// writer:
Configure<AbpBlobStoringEncryptionOptions>(o => o.ChunkSize = 4 * 1024 * 1024);
// reader (different deploy):
Configure<AbpBlobStoringEncryptionOptions>(o => o.ChunkSize = 1 * 1024 * 1024); // throws [90]

// after — keep the value identical across all deployments
const int Chunk = 4 * 1024 * 1024;
Configure<AbpBlobStoringEncryptionOptions>(o => o.ChunkSize = Chunk);
Defensive patterns

Strategy: validation

Validate before calling

// Ensure reader and writer use the same chunk size.
static void AssertMatchingChunkSize(int readerChunk, int writerChunk)
{
    if (readerChunk != writerChunk)
        throw new InvalidOperationException(
            $"Reader ChunkSize ({readerChunk}) differs from writer ({writerChunk}); re-encrypt the BLOBs.");
}
// Also sanity-check the stored object length is plausible for the format.

Type guard

public sealed record ChunkSize(int Value)
{
    public static ChunkSize Shared { get; } = new(4 * 1024 * 1024);
    public ChunkSize(int value)
    {
        if (value is < 1024 or > 64 * 1024 * 1024)
            throw new ArgumentOutOfRangeException(nameof(value));
        Value = value;
    }
}

Try / catch

try
{
    return await blob.GetAllBytesAsync(name);
}
catch (AbpException ex) when (ex.Message.Contains("invalid chunk length"))
{
    logger.LogError(ex, "BLOB '{Name}' has a corrupt length prefix or a ChunkSize mismatch.", name);
    throw;
}

Prevention

When it happens

Trigger: Decrypting with a chunkSize that does not match the one used at encryption time; bit-rot or tampering altered the length prefix; reading a non-encrypted stream as if it were encrypted (e.g. magic-header check bypassed).

Common situations: Changed AbpBlobStoringEncryptionOptions.ChunkSize between writing and reading without re-encrypting; storage corruption; reading a plaintext or differently-versioned BLOB through the encrypted provider.

Related errors


AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13). Data as JSON: /api/errors/d9172f9118135d0f. Report an issue: GitHub.