JeffreySu/WeiXinMPSDK · error · WxOpenException
SessionId无效
Error message
SessionId无效
What it means
Thrown by DecodeEncryptedDataBySessionId when SessionContainer.GetSession(sessionId) finds no session, so the encrypted data cannot be decrypted with a SessionKey. Raises WxOpenException "SessionId无效". Same family as CheckSignature's (01) error but in the decryption path.
Solutions
- Decrypt encrypted data soon after login while the session is still cached, or re-login to refresh the session
- Configure a shared distributed cache for SessionContainer across all instances
- Check session existence first with SessionContainer.GetSession(sessionId) and trigger re-login when null
- Catch WxOpenException and return a session-expired error code to the mini-program
Example fix
// before
var json = EncryptHelper.DecodeEncryptedDataBySessionId(sessionId, encryptedData, iv); // throws
// after
if (SessionContainer.GetSession(sessionId) == null) {
return LoginExpired(); // client re-runs wx.login
}
var json = EncryptHelper.DecodeEncryptedDataBySessionId(sessionId, encryptedData, iv); Defensive patterns
Strategy: validation
Validate before calling
if (SessionContainer.GetSession(sessionId) == null) {
return RequireRelogin(); // re-run wx.login + jscode2session
} Type guard
bool CanDecrypt(string sessionId) => SessionContainer.GetSession(sessionId) != null;
Try / catch
try {
var json = EncryptHelper.DecodeEncryptedDataBySessionId(sessionId, encryptedData, iv);
} catch (WxOpenException ex) when (ex.Message.Contains("SessionId无效")) {
return Unauthorized("session expired");
} Prevention
- Decrypt encrypted payloads promptly after login while the session is cached
- Configure SessionContainer with a distributed cache (Redis) for multi-instance deployments
- Notify the mini-program to re-login whenever decryption reports an invalid session
- Avoid long delays between wx.login and encrypted-data decryption
When it happens
Trigger: Calling DecodeEncryptedDataBySessionId(sessionId, encryptedData, iv) with an expired/unknown sessionId; using a sessionId obtained before a cache restart or on a different server without shared cache; client sending a wrong or fabricated id.
Common situations: Memory-cache eviction/timeout between login and decrypt (e.g. phone-number decrypt long after login); load-balanced servers each with local cache; stale frontend session after server redeploy.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- SessionId无效(01)
- SessionKey无效
- SessionKey无效(02)
- 凭据提供器返回了空 AppSecret。
- MsgType: 在RequestMessageFactory中没有对应的处理程序!
AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12).
Data as JSON: /api/errors/c0f406a845fd2a0c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen/Senparc.Weixin.WxOpen/Helpers/EncryptHelper.cs:251
var result = AES_Decrypt(encryptedData, aesIV, aesKey, keySize);
var resultStr = Encoding.UTF8.GetString(result);
return resultStr;
}
/// <summary>
/// 解密消息(通过SessionId获取)
/// </summary>
/// <param name="sessionId"></param>
/// <param name="encryptedData"></param>
/// <param name="iv"></param>
/// <exception cref="WxOpenException">当SessionId或SessionKey无效时抛出异常</exception>
/// <returns></returns>
public static string DecodeEncryptedDataBySessionId(string sessionId, string encryptedData, string iv)
{
var sessionBag = SessionContainer.GetSession(sessionId);
if (sessionBag == null)
{
throw new WxOpenException("SessionId无效");
}
if (string.IsNullOrEmpty(sessionBag.SessionKey))
{
throw new WxOpenException("SessionKey无效");
}
var resultStr = DecodeEncryptedData(sessionBag.SessionKey, encryptedData, iv);
return resultStr;
}
/// <summary>
/// 检查解密消息水印
/// </summary>
/// <param name="entity"></param>
/// <param name="appId"></param>
/// <returns>entity为null时也会返回false</returns>View on GitHub (pinned to be573f6f94)