AlexxIT/go2rtc · error
wrong message prefix
Error message
wrong message prefix
What it means
Roborock IoT Decrypt guard: the ciphertext is shorter than 32 bytes or does not start with the expected '1.0' protocol version prefix, so it is not a valid Roborock encrypted IPC message. Usually means desynced framing, wrong devKey, or a non-Roborock endpoint responding.
Solutions
- Verify the local devKey matches the device
- Check that the connection is talking to the Roborock IoT endpoint and framing is intact
- Reconnect to resynchronize the message stream
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at pkg/roborock/iot/crypto.go:20 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/1ae88c16fa7fccf8.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/roborock/iot/crypto.go:20
import (
"crypto/aes"
"crypto/md5"
"encoding/binary"
"errors"
"hash/crc32"
)
// key - convert timestamp to key
func (c *Codec) key(timestamp uint32) []byte {
const salt = "TXdfu$jyZ#TZHsg4"
key := md5.Sum([]byte(encodeTimestamp(timestamp) + c.devKey + salt))
return key[:]
}
func (c *Codec) Decrypt(cipherText []byte) ([]byte, error) {
if len(cipherText) < 32 || string(cipherText[:3]) != "1.0" {
return nil, errors.New("wrong message prefix")
}
i := len(cipherText) - 4
if binary.BigEndian.Uint32(cipherText[i:]) != crc32.ChecksumIEEE(cipherText[:i]) {
return nil, errors.New("wrong message checksum")
}
if proto := binary.BigEndian.Uint16(cipherText[15:]); proto != 102 {
return nil, nil
}
timestamp := binary.BigEndian.Uint32(cipherText[11:])
return decryptECB(cipherText[19:i], c.key(timestamp)), nil
}
func (c *Codec) Encrypt(plainText []byte, seq, random, timestamp uint32) []byte {
const proto = 101
View on GitHub (pinned to c245815e75)