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
- 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
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
- 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
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.