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

  1. Verify the EncodingAESKey matches the sending WeCom app — this error after 'invalid padding' style symptoms is nearly always a key mismatch
  2. Log msgLen vs len(plaintext) to distinguish key corruption (random msgLen) from truncation (msgLen slightly larger than buffer)
  3. Ensure no proxy rewrites the request body between WeCom and your endpoint
  4. 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

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


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/779fec8e32d67555. Report an issue: GitHub.