abpframework/abp · error · AbpException

BLOB encryption is enabled, but no passphrase could be resol

Error message

BLOB encryption is enabled, but no passphrase could be resolved. Pass a passphrase to the UseEncryption extension method or configure AbpBlobStoringEncryptionOptions.DefaultPassPhrase.

What it means

DefaultBlobEncryptionKeyProvider.ResolveForEncryptionAsync tries the container-level passphrase first, then AbpBlobStoringEncryptionOptions.DefaultPassPhrase. If neither is set (both null/whitespace) while encryption is enabled for the container/BLOB, no key can be derived and it throws AbpException describing both fix paths.

Source

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

    public virtual Task<BlobEncryptionKey> ResolveForEncryptionAsync(
        [NotNull] BlobEncryptionKeyContext context,
        CancellationToken cancellationToken = default)
    {
        Check.NotNull(context, nameof(context));
        cancellationToken.ThrowIfCancellationRequested();

        var containerPassPhrase = GetContainerPassPhraseOrNull(context.Configuration);
        if (!string.IsNullOrWhiteSpace(containerPassPhrase))
        {
            return Task.FromResult(new BlobEncryptionKey(BlobEncryptionKeySource.Container, containerPassPhrase!));
        }

        if (!string.IsNullOrWhiteSpace(Options.DefaultPassPhrase))
        {
            return Task.FromResult(new BlobEncryptionKey(BlobEncryptionKeySource.Global, Options.DefaultPassPhrase!));
        }

        throw new AbpException(
            "BLOB encryption is enabled, but no passphrase could be resolved. " +
            "Pass a passphrase to the UseEncryption extension method or configure " +
            $"{nameof(AbpBlobStoringEncryptionOptions)}.{nameof(AbpBlobStoringEncryptionOptions.DefaultPassPhrase)}."
        );
    }

    /// <inheritdoc />
    public virtual Task<string> ResolveForDecryptionAsync(
        BlobEncryptionKeySource keySource,
        [NotNull] BlobEncryptionKeyContext context,
        CancellationToken cancellationToken = default)
    {
        Check.NotNull(context, nameof(context));
        cancellationToken.ThrowIfCancellationRequested();

        string? passPhrase;
        switch (keySource)
        {

View on GitHub (pinned to 7ed43b1931)

Solutions

  1. Set AbpBlobStoringEncryptionOptions.DefaultPassPhrase globally in Configure<AbpBlobStoringEncryptionOptions>.
  2. Pass a passphrase explicitly to UseEncryption(passphrase) for the container.
  3. If passphrases are tenant/externally sourced, replace IBlobEncryptionKeyProvider with a custom implementation that resolves them.
  4. Verify the configuration module actually runs before any BLOB save (check DI/module loading order).

Example fix

// before — encryption enabled, no passphrase anywhere
Configure<AbpBlobStoringOptions>(o =>
    o.Containers.Configure<MyContainer>(c => c.UseEncryption()));
await blob.SaveAsync("x", bytes); // throws [99]

// after — set a global default passphrase
Configure<AbpBlobStoringEncryptionOptions>(o =>
    o.DefaultPassPhrase = Environment.GetEnvironmentVariable("BLOB_PASSPHRASE")
        ?? throw new InvalidOperationException("BLOB_PASSPHRASE not set"));
// or per-container:
// c.UseEncryption(opts => opts.PassPhrase = "...");
Defensive patterns

Strategy: validation

Validate before calling

// Startup assertion: encryption is configured with a real passphrase.
static void AssertEncryptionConfigured(
    AbpBlobStoringOptions storing,
    AbpBlobStoringEncryptionOptions encryption)
{
    bool anyEncrypted = storing.Containers.GetConfigurations()
        .Any(c => c.Configuration.GetBlobEncryptionEnabled());
    if (anyEncrypted && string.IsNullOrWhiteSpace(encryption.DefaultPassPhrase))
        throw new InvalidOperationException(
            "BLOB encryption is enabled but no DefaultPassPhrase is set " +
            "and no container-level passphrase was provided.");
}

Type guard

public sealed record NonBlankPassphrase
{
    public string Value { get; }
    public NonBlankPassphrase(string? value)
    {
        Value = string.IsNullOrWhiteSpace(value)
            ? throw new ArgumentException("passphrase required")
            : value;
    }
}
// Configure<AbpBlobStoringEncryptionOptions>(o => o.DefaultPassPhrase = new NonBlankPassphrase(env).Value);

Try / catch

try
{
    await blob.SaveAsync(name, data);
}
catch (AbpException ex) when (ex.Message.Contains("no passphrase could be resolved"))
{
    logger.LogCritical(ex, "Encryption enabled but no passphrase configured; set DefaultPassPhrase or pass one to UseEncryption.");
    // Not retryable until config is fixed.
    throw;
}

Prevention

When it happens

Trigger: Saving a BLOB to a container configured with UseEncryption() but with no per-container passphrase passed to UseEncryption and no DefaultPassPhrase set in AbpBlobStoringEncryptionOptions.

Common situations: Forgot to configure DefaultPassPhrase in appsettings/startup; container configured for encryption in one module but the passphrase configured in another module that didn't load; passphrase left empty in the secret store; module-load ordering issue.

Related errors


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