Garbled messages
CheckSum mismatch: invalid checksum (tag 10)
The three-digit value in CheckSum (10) does not match the sum of the message bytes modulo 256. The receiver treats the message as garbled and ignores it; the next message then shows up as a sequence gap.
What it means
CheckSum is the sum of every byte from the start of 8= up to and including the SOH before 10=, modulo 256, written as exactly three digits. A sum of 7 is sent as 007.
It is a transmission check, not a security feature. A mismatch almost always means the sender computed it over different bytes from the ones it sent.
Like a bad BodyLength, a bad CheckSum gets no Reject. The message is dropped and its sequence number is not consumed.
Common causes
- No zero padding: 10=92 instead of 10=092.
- Computed over a copy of the message that uses | or ^ instead of SOH.
- A field changed after the checksum was computed, often by a gateway, or by a replay that added PossDupFlag.
- Summing characters instead of bytes for non-ASCII text.
- Including the 10= field itself, or leaving out the last SOH before it.
How to fix it
On the side that sent the message
- Compute CheckSum last, over the exact bytes you write to the socket, and pad it to three digits.
- If something between your engine and the counterparty rewrites fields, it must recompute BodyLength and CheckSum.
- Paste the message into the parser to see the expected value.
On the side that raised the error
- Log the raw bytes of dropped messages and send them to the counterparty with the expected value.
- Check that your own logging does not alter the bytes you compare. Some loggers replace SOH, which makes a correct message look wrong when it is checked from the log.
Example
A Heartbeat with a wrong CheckSum, then the same message with the correct value.
1. Wrong CheckSum
8=FIX.4.4|9=61|35=0|49=SELLSIDE|56=BUYSIDE|34=2210|52=20261020-12:00:30.000|10=197|
2. Correct CheckSum
8=FIX.4.4|9=61|35=0|49=SELLSIDE|56=BUYSIDE|34=2210|52=20261020-12:00:30.000|10=180|
SOH (0x01) is shown as |. BodyLength (9) and CheckSum (10) are calculated as if every | were SOH, except where the example is about a wrong value.
Open this example in the parserQuestions
- How is the FIX checksum calculated?
- Add up the value of every byte from the 8 of 8= to the SOH just before 10=, take the total modulo 256 and write it as three digits with leading zeros.
- Do I compute the checksum with | or with SOH?
- With SOH (0x01). The | in logs is only for display. The parser computes the value as if every delimiter were SOH, whatever delimiter the log uses.