alibaba/spring-ai-alibaba · error

解密apiKey失败: {}

Error message

解密apiKey失败: {}

What it means

buildModelConfigDOFromModelConfigInfo decrypts the provider's apiKey with RSACryptUtils.decrypt; on failure it logs this warning and continues using the encrypted value. The built ModelConfigDO will contain ciphertext as the API key, causing authentication failures on model calls.

Source

Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/service/impl/ModelConfigBridgeServiceImpl.java:347

     */
    private ModelConfigDO buildModelConfigDOFromModelConfigInfo(ModelConfigInfo modelConfigInfo, Long id) {
        try {
            ProviderConfigInfo providerDetail = providerManager.getProviderDetail(modelConfigInfo.getProvider(), false);
            if (providerDetail == null) {
                return null;
            }

            ModelCredential credential = providerDetail.getCredential();
            if (credential == null) {
                return null;
            }

            String apiKey = credential.getApiKey();
            if (StringUtils.isNotBlank(apiKey)) {
                try {
                    apiKey = RSACryptUtils.decrypt(apiKey);
                } catch (Exception e) {
                    log.warn("解密apiKey失败: {}", e.getMessage());
                }
            }

            String baseUrl = credential.getEndpoint();
            if (StringUtils.isNotBlank(baseUrl)) {
                if (baseUrl.endsWith("/v1") || baseUrl.endsWith("/v1/")) {
                    baseUrl = baseUrl.replaceAll("/v1/?$", "");
                }
            } else {
                baseUrl = getDefaultBaseUrl(modelConfigInfo.getProvider());
            }

            return ModelConfigDO.builder()
                    .id(id)
                    .name(modelConfigInfo.getName())
                    .provider(modelConfigInfo.getProvider().toLowerCase())
                    .modelName(modelConfigInfo.getModelId())
                    .baseUrl(baseUrl)

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Re-enter the API key via the admin UI so it is encrypted with the current key
  2. Align RSACryptUtils key configuration across environments (same private key as the encrypting environment)
  3. Re-encrypt all stored credentials after key rotation using a migration script
  4. Monitor for this warning in logs — model calls will fail auth downstream

Example fix

// before
String apiKey = credential.getApiKey(); // ciphertext used directly
// after
String apiKey = credential.getApiKey();
if (!isPlaintextValid(apiKey)) { reSaveCredentialWithCurrentKey(provider); }
Defensive patterns

Strategy: fallback

Try / catch

try { chatWith(config); } catch (AuthenticationException e) { reSaveApiKeyWithCurrentRsaKey(provider); }

Prevention

When it happens

Trigger: Credential apiKey stored under a different RSA key pair than the current RSACryptUtils configuration, or the stored value was never encrypted (plaintext inserted directly).

Common situations: Environment migration with different RSA keys; key rotation without re-encrypting secrets; manual DB edits inserting plaintext keys; shared DB across deployments with distinct key configs.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/e6ab3431a6358b3b. Report an issue: GitHub.