alibaba/spring-ai-alibaba · error

解密apiKey失败,使用原始值: {}

Error message

解密apiKey失败,使用原始值: {}

What it means

When decrypting the provider's stored apiKey with RSACryptUtils.decrypt fails, this warning is logged and the raw (still-encrypted) value is used as-is. The call succeeds but downstream model calls will likely fail authentication because the API key is ciphertext.

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:233

            ProviderConfigInfo providerDetail = providerManager.getProviderDetail(modelEntity.getProvider(), false);
            if (providerDetail == null) {
                log.warn("Provider不存在: {}", modelEntity.getProvider());
                return null;
            }

            ModelCredential credential = providerDetail.getCredential();
            if (credential == null) {
                log.warn("Provider的credential不存在: {}", modelEntity.getProvider());
                return null;
            }

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

            // 获取baseUrl,从credential的endpoint获取
            String baseUrl = credential.getEndpoint();
            if (StringUtils.isNotBlank(baseUrl)) {
                // 移除/v1后缀(如果存在),因为Spring AI会自动添加
                if (baseUrl.endsWith("/v1") || baseUrl.endsWith("/v1/")) {
                    baseUrl = baseUrl.replaceAll("/v1/?$", "");
                }
            } else {
                // 如果没有endpoint,使用默认值(根据provider类型)
                baseUrl = getDefaultBaseUrl(modelEntity.getProvider());
            }

            // 转换时间
            LocalDateTime createTime = convertToLocalDateTime(modelEntity.getGmtCreate());
            LocalDateTime updateTime = convertToLocalDateTime(modelEntity.getGmtModified());

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Re-save the API key through the admin UI so it is encrypted with the current RSA key pair
  2. Restore the original RSA private key used when the credential was encrypted
  3. Check RSACryptUtils key configuration (env/config) matches the environment where the key was encrypted
  4. Do not ignore this warning in production — the raw ciphertext will be sent as the API key and fail auth

Example fix

// before: plaintext key inserted directly in DB
INSERT INTO credential(api_key) VALUES ('sk-xxxx');
// after: encrypt before storing
INSERT INTO credential(api_key) VALUES (RSA_ENCRYPT('sk-xxxx'));
Defensive patterns

Strategy: fallback

Validate before calling

if (!RSACryptUtils.isEncryptedFormat(credential.getApiKey())) { reSaveCredential(provider); }

Type guard

boolean keyLooksEncrypted(String k) { return k != null && k.startsWith("RSA"); }

Try / catch

try { use(do.getEntity().getApiKey()); } catch (AuthException e) { reEncryptStoredCredentials(); }

Prevention

When it happens

Trigger: The stored apiKey is not valid RSA-encrypted content for the current key pair — e.g. plaintext key stored directly, or data encrypted with a different/rotated RSA key.

Common situations: Manually inserting a plaintext apiKey into the credential store; rotating or regenerating the RSA key pair without re-encrypting stored credentials; migrating data between environments with different keys.

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/7f37f740db44a293. Report an issue: GitHub.