abpframework/abp · error · AbpException

Unknown BLOB encryption key source: {keySource}!

Error message

Unknown BLOB encryption key source: {keySource}!

What it means

The default branch of the switch over BlobEncryptionKeySource in ResolveForDecryptionAsync. It fires when the keySource value recorded in the BLOB header does not match Container, Tenant, or Global. This is a defensive guard: the enum is a byte stored in the BLOB, so an out-of-range value indicates either a future enum value the default provider does not yet know, or BLOB header corruption.

Source

Thrown at framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/DefaultBlobEncryptionKeyProvider.cs:75

        cancellationToken.ThrowIfCancellationRequested();

        string? passPhrase;
        switch (keySource)
        {
            case BlobEncryptionKeySource.Container:
                passPhrase = GetContainerPassPhraseOrNull(context.Configuration);
                break;
            case BlobEncryptionKeySource.Tenant:
                throw new AbpException(
                    "The BLOB was encrypted with a tenant-specific passphrase, but the default " +
                    $"key provider does not supply tenant keys. Replace the {nameof(IBlobEncryptionKeyProvider)} " +
                    "service with the implementation that was used to encrypt the BLOB."
                );
            case BlobEncryptionKeySource.Global:
                passPhrase = Options.DefaultPassPhrase;
                break;
            default:
                throw new AbpException($"Unknown BLOB encryption key source: {keySource}!");
        }

        if (string.IsNullOrWhiteSpace(passPhrase))
        {
            throw new AbpException(
                $"The BLOB was encrypted with the '{keySource}' passphrase, " +
                "but that passphrase is not available anymore, so the BLOB can not be decrypted."
            );
        }

        return Task.FromResult(passPhrase!);
    }

    /// <summary>
    /// Returns the container-specific passphrase, so derived providers can keep it
    /// as the highest-priority source.
    /// </summary>
    protected virtual string? GetContainerPassPhraseOrNull(BlobContainerConfiguration configuration)

View on GitHub (pinned to 7ed43b1931)

Solutions

  1. Align the BlobStoring package version on the reading host with (or newer than) the host that wrote the BLOB.
  2. Inspect the BLOB header bytes to confirm the recorded key source value; if corrupted, restore the BLOB from backup.
  3. If you extended BlobEncryptionKeySource with a custom value, subclass DefaultBlobEncryptionKeyProvider and override ResolveForDecryptionAsync to handle it.
  4. Re-encrypt the BLOB with a known key source after fixing the version skew.

Example fix

// before: default switch throws on a custom/unknown key source
// after: override to handle the extra source
public class ExtendedBlobEncryptionKeyProvider : DefaultBlobEncryptionKeyProvider
{
    public override Task<string> ResolveForDecryptionAsync(BlobEncryptionKeySource keySource, BlobEncryptionKeyContext context, CancellationToken ct = default)
    {
        if (Enum.IsDefined(typeof(BlobEncryptionKeySource), keySource))
            return base.ResolveForDecryptionAsync(keySource, context, ct);

        throw new AbpException($"Unrecognized key source byte '{(byte)keySource}' in BLOB header; possible corruption or version skew.");
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// Reject unknown key source bytes before calling the provider.
if (!Enum.IsDefined(typeof(BlobEncryptionKeySource), keySource))
{
    throw new InvalidDataException($"BLOB header records an unrecognized key source byte: {(byte)keySource}.");
}

Type guard

public static bool IsKnownKeySource(BlobEncryptionKeySource source) =>
    Enum.IsDefined(typeof(BlobEncryptionKeySource), source);

Try / catch

try
{
    phrase = await keyProvider.ResolveForDecryptionAsync(keySource, context, ct);
}
catch (AbpException ex) when (ex.Message.Contains("Unknown BLOB encryption key source", StringComparison.Ordinal))
{
    logger.LogError("Possible version skew or BLOB header corruption; key source byte = {Byte}.", (byte)keySource);
    throw;
}

Prevention

When it happens

Trigger: ResolveForDecryptionAsync receives a BlobEncryptionKeySource whose underlying byte is not 1, 2, or 3. Occurs when a newer version of the library wrote a new enum value into the BLOB header and an older runtime reads it, or when the header bytes are physically corrupted.

Common situations: Downgrading the ABP BlobStoring package to a version that predates a newly added BlobEncryptionKeySource member; reading a BLOB whose encryption header was tampered with or truncated; mixing incompatible library versions across write and read hosts.

Related errors


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