{"record":{"id":"0af70318d36a87c6","repo":"abpframework/abp","slug":"the-blob-was-encrypted-with-the-keysource-pass","errorCode":null,"errorMessage":"The BLOB was encrypted with the '{keySource}' passphrase, but that passphrase is not available anymore, so the BLOB can not be decrypted.","messagePattern":"The BLOB was encrypted with the '(.+?)' passphrase, but that passphrase is not available anymore, so the BLOB can not be decrypted\\.","errorType":"exception","errorClass":"AbpException","httpStatus":null,"severity":"error","filePath":"framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/DefaultBlobEncryptionKeyProvider.cs","lineNumber":80,"sourceCode":"            case BlobEncryptionKeySource.Container:\n                passPhrase = GetContainerPassPhraseOrNull(context.Configuration);\n                break;\n            case BlobEncryptionKeySource.Tenant:\n                throw new AbpException(\n                    \"The BLOB was encrypted with a tenant-specific passphrase, but the default \" +\n                    $\"key provider does not supply tenant keys. Replace the {nameof(IBlobEncryptionKeyProvider)} \" +\n                    \"service with the implementation that was used to encrypt the BLOB.\"\n                );\n            case BlobEncryptionKeySource.Global:\n                passPhrase = Options.DefaultPassPhrase;\n                break;\n            default:\n                throw new AbpException($\"Unknown BLOB encryption key source: {keySource}!\");\n        }\n\n        if (string.IsNullOrWhiteSpace(passPhrase))\n        {\n            throw new AbpException(\n                $\"The BLOB was encrypted with the '{keySource}' passphrase, \" +\n                \"but that passphrase is not available anymore, so the BLOB can not be decrypted.\"\n            );\n        }\n\n        return Task.FromResult(passPhrase!);\n    }\n\n    /// <summary>\n    /// Returns the container-specific passphrase, so derived providers can keep it\n    /// as the highest-priority source.\n    /// </summary>\n    protected virtual string? GetContainerPassPhraseOrNull(BlobContainerConfiguration configuration)\n    {\n        return BlobEncryptionConfiguration.GetPassPhraseOrNull(configuration);\n    }\n}\n","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/DefaultBlobEncryptionKeyProvider.cs#L62-L98","documentation":"Thrown after the switch in ResolveForDecryptionAsync resolves the key source but the resulting passphrase is null, empty, or whitespace. The BLOB header knows which source was used (container or global), but that source no longer yields a value, so decryption is impossible. This is distinct from error 100 (unsupported source) and error 101 (unknown source).","triggerScenarios":"keySource is Container but GetContainerPassPhraseOrNull returns null (no per-container passphrase configured), or keySource is Global but AbpBlobStoringEncryptionOptions.DefaultPassPhrase is unset/blank. The BLOB was encrypted when the passphrase existed; it was later removed or renamed in configuration.","commonSituations":"Rotating or deleting a passphrase without re-encrypting existing BLOBs; moving config between environments where AbpBlobStoringEncryptionOptions.DefaultPassPhrase was not copied; removing the UseEncryption(...) container passphrase; changing appsettings without the encryption block.","solutions":["Restore the passphrase that was active when the BLOB was encrypted (container passphrase via UseEncryption, or AbpBlobStoringEncryptionOptions.DefaultPassPhrase), then decrypt.","If the original passphrase is truly lost, accept the BLOB is unrecoverable and re-create it.","Maintain a passphrase history/keystore so older BLOBs can always be decrypted during rotations.","After restoring access, re-encrypt the BLOB with the current passphrase and update tooling to prevent silent passphrase removal."],"exampleFix":"// before: DefaultPassPhrase was removed from appsettings, decryption fails\n// after: restore the original global passphrase in the module\nConfigure<AbpBlobStoringEncryptionOptions>(options =>\n{\n    options.DefaultPassPhrase = _originalPassPhraseFromSecretStore;\n});","handlingStrategy":"validation","validationCode":"// Verify the recorded key source still resolves to a passphrase before decryption.\nvar probe = keySource switch\n{\n    BlobEncryptionKeySource.Container => containerPassPhrase,\n    BlobEncryptionKeySource.Global => options.DefaultPassPhrase,\n    _ => null\n};\nif (string.IsNullOrWhiteSpace(probe))\n{\n    throw new InvalidOperationException($\"The passphrase for key source '{keySource}' is no longer configured; decryption will fail.\");\n}","typeGuard":"public static bool HasPassphraseForSource(BlobEncryptionKeySource source, string? containerPhrase, AbpBlobStoringEncryptionOptions opts) =>\n    source switch\n    {\n        BlobEncryptionKeySource.Container => !string.IsNullOrWhiteSpace(containerPhrase),\n        BlobEncryptionKeySource.Global => !string.IsNullOrWhiteSpace(opts.DefaultPassPhrase),\n        _ => false\n    };","tryCatchPattern":"try\n{\n    phrase = await keyProvider.ResolveForDecryptionAsync(keySource, context, ct);\n}\ncatch (AbpException ex) when (ex.Message.Contains(\"not available anymore\", StringComparison.Ordinal))\n{\n    logger.LogError(ex, \"Passphrase for source {Source} is missing; restore config or re-encrypt the BLOB.\", keySource);\n    throw;\n}","preventionTips":["Treat passphrases as immutable operational secrets; never delete one without re-encrypting affected BLOBs.","Keep a passphrase history so rotated keys can still decrypt legacy BLOBs.","Add a startup health check that confirms the expected passphrases are configured.","Alert when a configured container/global passphrase becomes null or empty."],"tags":["blob-storing","encryption","configuration","key-management"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}