{"record":{"id":"7f37f740db44a293","repo":"alibaba/spring-ai-alibaba","slug":"apikey-7f37f7","errorCode":null,"errorMessage":"解密apiKey失败，使用原始值: {}","messagePattern":"解密apiKey失败，使用原始值: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/service/impl/ModelConfigBridgeServiceImpl.java","lineNumber":233,"sourceCode":"            ProviderConfigInfo providerDetail = providerManager.getProviderDetail(modelEntity.getProvider(), false);\n            if (providerDetail == null) {\n                log.warn(\"Provider不存在: {}\", modelEntity.getProvider());\n                return null;\n            }\n\n            ModelCredential credential = providerDetail.getCredential();\n            if (credential == null) {\n                log.warn(\"Provider的credential不存在: {}\", modelEntity.getProvider());\n                return null;\n            }\n\n            // 解密apiKey\n            String apiKey = credential.getApiKey();\n            if (StringUtils.isNotBlank(apiKey)) {\n                try {\n                    apiKey = RSACryptUtils.decrypt(apiKey);\n                } catch (Exception e) {\n                    log.warn(\"解密apiKey失败，使用原始值: {}\", e.getMessage());\n                }\n            }\n\n            // 获取baseUrl，从credential的endpoint获取\n            String baseUrl = credential.getEndpoint();\n            if (StringUtils.isNotBlank(baseUrl)) {\n                // 移除/v1后缀（如果存在），因为Spring AI会自动添加\n                if (baseUrl.endsWith(\"/v1\") || baseUrl.endsWith(\"/v1/\")) {\n                    baseUrl = baseUrl.replaceAll(\"/v1/?$\", \"\");\n                }\n            } else {\n                // 如果没有endpoint，使用默认值（根据provider类型）\n                baseUrl = getDefaultBaseUrl(modelEntity.getProvider());\n            }\n\n            // 转换时间\n            LocalDateTime createTime = convertToLocalDateTime(modelEntity.getGmtCreate());\n            LocalDateTime updateTime = convertToLocalDateTime(modelEntity.getGmtModified());","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/service/impl/ModelConfigBridgeServiceImpl.java#L215-L251","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-save the API key through the admin UI so it is encrypted with the current RSA key pair","Restore the original RSA private key used when the credential was encrypted","Check RSACryptUtils key configuration (env/config) matches the environment where the key was encrypted","Do not ignore this warning in production — the raw ciphertext will be sent as the API key and fail auth"],"exampleFix":"// before: plaintext key inserted directly in DB\nINSERT INTO credential(api_key) VALUES ('sk-xxxx');\n// after: encrypt before storing\nINSERT INTO credential(api_key) VALUES (RSA_ENCRYPT('sk-xxxx'));","handlingStrategy":"fallback","validationCode":"if (!RSACryptUtils.isEncryptedFormat(credential.getApiKey())) { reSaveCredential(provider); }","typeGuard":"boolean keyLooksEncrypted(String k) { return k != null && k.startsWith(\"RSA\"); }","tryCatchPattern":"try { use(do.getEntity().getApiKey()); } catch (AuthException e) { reEncryptStoredCredentials(); }","preventionTips":["Use one RSA key pair per environment and store it consistently","Re-encrypt credentials after key rotation","Never insert plaintext keys directly into the DB","Alert on this warning in production"],"tags":["encryption","api-key","rsa"],"backgroundTag":"invalid-config-value","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}