Tencent/WeKnora · error
message length mismatch
Error message
message length mismatch
What it means
decrypt() reads msgLen from plaintext[16:20] (big-endian uint32) and requires len(plaintext) >= 20+msgLen, i.e. the declared message must actually fit in the buffer. A mismatch means the length header doesn't match the remaining bytes — the signature of decrypting with the wrong key or of corrupted/truncated data. It prevents slicing out-of-bounds or trusting attacker-controlled lengths.
Source
Thrown at internal/im/wecom/webhook_adapter.go:489
padLen := int(ciphertext[len(ciphertext)-1])
if padLen > wecomPKCS7BlockSize || padLen == 0 || padLen > len(ciphertext) {
return nil, fmt.Errorf("invalid padding")
}
for i := 0; i < padLen; i++ {
if ciphertext[len(ciphertext)-1-i] != byte(padLen) {
return nil, fmt.Errorf("invalid padding")
}
}
plaintext := ciphertext[:len(ciphertext)-padLen]
// WeCom format: random(16) + msg_len(4) + msg + corp_id
if len(plaintext) < 20 {
return nil, fmt.Errorf("plaintext too short")
}
msgLen := binary.BigEndian.Uint32(plaintext[16:20])
if uint32(len(plaintext)) < 20+msgLen {
return nil, fmt.Errorf("message length mismatch")
}
msgBytes := plaintext[20 : 20+msgLen]
// Verify corp_id from plaintext tail
corpIDBytes := plaintext[20+msgLen:]
if string(corpIDBytes) != a.corpID {
return nil, fmt.Errorf("corp_id mismatch: expected %s, got %s", a.corpID, string(corpIDBytes))
}
return msgBytes, nil
}
// callbackRequestBody is the XML structure of a WeCom callback request body.
type callbackRequestBody struct {
XMLName xml.Name `xml:"xml"`
ToUserName string `xml:"ToUserName"`
Encrypt string `xml:"Encrypt"`View on GitHub (pinned to 988cbb0330)
Solutions
- Verify the EncodingAESKey matches the sending WeCom app — this error after 'invalid padding' style symptoms is nearly always a key mismatch
- Log msgLen vs len(plaintext) to distinguish key corruption (random msgLen) from truncation (msgLen slightly larger than buffer)
- Ensure no proxy rewrites the request body between WeCom and your endpoint
- Treat repeated mismatches as potential forged traffic and enable signature verification of msg_signature before decrypt
Defensive patterns
Strategy: try-catch
Try / catch
if err != nil && strings.Contains(err.Error(), "message length mismatch") {
logger.Warnf("WeCom callback length mismatch (forged or corrupted?) sig=%s", msgSignature)
http.Error(w, "bad payload", http.StatusBadRequest)
return
} Prevention
- Always verify msg_signature (HMAC-SHA1 of token/timestamp/nonce/encrypt) before decrypt so forged bodies never reach this check
- Keep proxies from rewriting the callback body
- Monitor mismatches as a security signal
When it happens
Trigger: Garbage msgLen from a wrong-key decryption; ciphertext truncated mid-message; crafted callback bodies where the embedded length exceeds the actual plaintext (possibly malicious).
Common situations: Wrong EncodingAESKey (most common); truncation by an HTTP intermediary; malicious forged callbacks probing the parser — this check is a security boundary.
Related errors
- plaintext too short
- ciphertext too short
- ciphertext length is not a multiple of AES block size
- invalid padding
- decrypt message: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/779fec8e32d67555.
Report an issue: GitHub.