iflytek/astron-agent · error · AesException
-40005
-40005
Error message
AppId validation failed
What it means
decrypt() extracts the receiving appid appended after the XML body in the plaintext and compares it to the configured appId. On mismatch it throws AesException(-40005, ValidateAppidError). This proves decryption succeeded but the message belongs to a different WeChat app.
Solutions
- Route by appid before decryption: extract the appid from the callback URL/query or from a per-corps token registry, and build WXBizMsgCrypt with the matching appId+aesKey
- Confirm the appId passed to the WXBizMsgCrypt constructor equals the app configured in the WeChat console for that callback URL
- If intentionally serving one app, verify which app actually sent the message (check the log) and fix the config drift
- For multi-app setups, maintain a map appId -> (token, aesKey) and retry decryption with the correct entry
Example fix
// before WXBizMsgCrypt crypt = new WXBizMsgCrypt(globalToken, globalKey, globalAppId); // -40005 for other apps // after AppCfg cfg = appRegistry.byCallbackUrl(callbackUrl); // or resolved earlier WXBizMsgCrypt crypt = new WXBizMsgCrypt(cfg.getToken(), cfg.getAesKey(), cfg.getAppId());
Defensive patterns
Strategy: try-catch
Try / catch
try { String xml = crypt.decrypt(encrypt, signature, timestamp, nonce); } catch (AesException e) { if (e.getCode() == -40005) { log.warn("appid mismatch on callback — message belongs to another app"); throw new UnknownAppCallbackException(); } throw e; } Prevention
- Resolve token/aesKey/appId per app instead of a global singleton cryptor
- Keep environment appid config in sync with the WeChat console
- Log the configured vs expected appid on failure to spot config drift quickly
When it happens
Trigger: One callback endpoint serving multiple WeChat official accounts/miniprograms while constructed with a single fixed appId; a message arriving for tenant/app B is decrypted with app A's key config and fails the appid check.
Common situations: Multi-tenant deployments sharing a callback URL, environments pointing at production appid with a test token/key mix, or an app renamed/rotated in the WeChat console without updating local config.
Related errors
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/51a1c06aa697c21d.
Report an issue: GitHub.
Appendix: source
Thrown at console/backend/hub/src/main/java/com/iflytek/astron/console/hub/util/wechat/WXBizMsgCrypt.java:187
// Remove padding
byte[] bytes = PKCS7Encoder.decode(original);
// Separate 16-bit random string, network byte order, and appId
byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
int xmlLength = recoverNetworkBytesOrder(networkOrder);
xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET);
from_appid = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length),
CHARSET);
} catch (Exception e) {
e.printStackTrace();
throw new AesException(AesException.IllegalBuffer);
}
// Verify appid
if (!from_appid.equals(appId)) {
throw new AesException(AesException.ValidateAppidError);
}
return xmlContent;
}
/**
* Verify URL
*
* @param msgSignature Signature string
* @param timeStamp Timestamp
* @param nonce Random number
* @param echoStr Random string
* @return Decrypted echostr
* @throws AesException Execution failed, please check the error code and specific error message of
* this exception
*/
public String verifyUrl(String msgSignature, String timeStamp, String nonce, String echoStr)
throws AesException {View on GitHub (pinned to 5e758547a8)