binarywang/WxJava · error · WxErrorException
会话存档secret未配置
Error message
会话存档secret未配置
What it means
Thrown (as checked WxErrorException) by getMsgAuditAccessToken() in the default WxCpServiceImpl when the chat-archive secret is null or blank. The msg-audit secret is a dedicated credential for the 会话存档 feature, separate from both the corp secret and the contact secret.
Source
Thrown at weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceImpl.java:132
}
@Override
public String getMsgAuditAccessToken(boolean forceRefresh) throws WxErrorException {
final WxCpConfigStorage configStorage = getWxCpConfigStorage();
if (!configStorage.isMsgAuditAccessTokenExpired() && !forceRefresh) {
return configStorage.getMsgAuditAccessToken();
}
Lock lock = configStorage.getMsgAuditAccessTokenLock();
lock.lock();
try {
// 拿到锁之后,再次判断一下最新的token是否过期,避免重刷
if (!configStorage.isMsgAuditAccessTokenExpired() && !forceRefresh) {
return configStorage.getMsgAuditAccessToken();
}
// 使用会话存档secret获取access_token
String msgAuditSecret = configStorage.getMsgAuditSecret();
if (msgAuditSecret == null || msgAuditSecret.trim().isEmpty()) {
throw new WxErrorException("会话存档secret未配置");
}
String url = String.format(configStorage.getApiUrl(WxCpApiPathConsts.GET_TOKEN),
this.configStorage.getCorpId(), msgAuditSecret);
try {
HttpGet httpGet = new HttpGet(url);
if (getRequestHttpProxy() != null) {
RequestConfig config = RequestConfig.custom().setProxy(getRequestHttpProxy()).build();
httpGet.setConfig(config);
}
String resultContent = getRequestHttpClient().execute(httpGet, ApacheBasicResponseHandler.INSTANCE);
WxError error = WxError.fromJson(resultContent, WxType.CP);
if (error.getErrorCode() != 0) {
throw new WxErrorException(error);
}
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
configStorage.updateMsgAuditAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
} catch (IOException e) {View on GitHub (pinned to 1c43293a3c)
Solutions
- Call configStorage.setMsgAuditSecret("...") during initialization
- In Spring Boot, set wx.cp.msg-audit-secret in application.yml
- Enable the 会话存档 feature in the WeChat Work admin console and copy the secret
- Also set msgAuditPriKey — decryption will fail without it even if the token succeeds
Example fix
// before
config.setCorpId(corpId);
config.setCorpSecret(corpSecret);
// msgAuditSecret and msgAuditPriKey missing
// after
config.setMsgAuditSecret(System.getenv("WX_CP_MSG_AUDIT_SECRET"));
config.setMsgAuditPriKey(System.getenv("WX_CP_MSG_AUDIT_PRI_KEY")); Defensive patterns
Strategy: validation
Validate before calling
// Validate msg-audit secret and private key at startup
String secret = configStorage.getMsgAuditSecret();
String priKey = configStorage.getMsgAuditPriKey();
if (StringUtils.isBlank(secret) || StringUtils.isBlank(priKey)) {
throw new IllegalStateException("会话存档功能需要同时配置 msgAuditSecret 和 msgAuditPriKey");
} Prevention
- Set both msgAuditSecret and msgAuditPriKey during initialization
- Enable 会话存档 in the WeChat Work admin console before using these APIs
- For Spring Boot, configure wx.cp.msg-audit-secret and wx.cp.msg-audit-pri-key
- Store the RSA private key securely (env var or secret manager)
When it happens
Trigger: Any msg-audit operation (chat records, media files, agreement info) through the default WxCpServiceImpl when configStorage.getMsgAuditSecret() is null or empty.
Common situations: Config object created without calling setMsgAuditSecret(); the 会话存档 feature is not enabled in the WeChat admin console; the secret env var is absent in production; using WxCpInMemoryConfigStorage which loses state on restart.
Related errors
AI-assisted analysis of binarywang/WxJava@1c43293a3c (2026-08-14).
Data as JSON: /api/errors/88847b0dad1f16fd.
Report an issue: GitHub.