{"record":{"id":"0620b0ea58741291","repo":"vitessio/vitess","slug":"can-t-strip-checksum-from-binlog-event-v-event-0620b0","errorCode":null,"errorMessage":"can't strip checksum from binlog event: %v, event data: %#v","messagePattern":"can't strip checksum from binlog event: (.+?), event data: %#v","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletserver/vstreamer/vstreamer.go","lineNumber":554,"sourceCode":"\t\treturn nil, nil\n\t}\n\n\t// We can't parse anything until we get a FORMAT_DESCRIPTION_EVENT that\n\t// tells us the size of the event header.\n\tif vs.format.IsZero() {\n\t\t// The only thing that should come before the FORMAT_DESCRIPTION_EVENT\n\t\t// is a fake ROTATE_EVENT, which the primary sends to tell us the name\n\t\t// of the current log file.\n\t\tif ev.IsRotate() {\n\t\t\treturn nil, nil\n\t\t}\n\t\treturn nil, fmt.Errorf(\"got a real event before FORMAT_DESCRIPTION_EVENT: %#v\", ev)\n\t}\n\n\t// Strip the checksum, if any. We don't actually verify the checksum, so discard it.\n\tev, _, err := ev.StripChecksum(vs.format)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"can't strip checksum from binlog event: %v, event data: %#v\", err, ev)\n\t}\n\n\tshouldSend := func(evType binlogdatapb.VEventType) bool {\n\t\tif vs.eventTypesToStream != nil && !vs.eventTypesToStream[evType] {\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\t}\n\n\ttimeNowUnixNano := time.Now().UnixNano()\n\tvar vevents []*binlogdatapb.VEvent\n\tswitch {\n\tcase ev.IsRotate(), ev.IsStop():\n\t\tvs.eventGTID = nil\n\tcase ev.IsPreviousGTIDs():\n\t\tif !shouldSend(binlogdatapb.VEventType_PREVIOUS_GTIDS) {\n\t\t\treturn nil, nil\n\t\t}","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go#L536-L572","documentation":"After the format description is known, vstreamer strips the trailing checksum bytes from each binlog event using the format recorded in the FORMAT_DESCRIPTION_EVENT. If StripChecksum fails, the event bytes do not match the declared format, so the event cannot be safely decoded and the stream is aborted.","triggerScenarios":"parseEvent calls ev.StripChecksum(vs.format) and it returns an error — typically because the event's declared checksum type/length disagrees with the actual buffer size or the format captured earlier.","commonSituations":"Mixing events from servers with different checksum settings (binlog_checksum OFF vs CRC32) across a failover; corrupted binlog bytes; a relay/middleman that truncates or rewrites events.","solutions":["Check that binlog_checksum is consistent across all MySQL servers in the topology","Restart the vstream so a fresh FORMAT_DESCRIPTION_EVENT is captured for the current server","Verify binlog file integrity with mysqlbinlog --verify-binlog-checksum","Inspect for proxies or binlog filtering tools altering event payloads between MySQL and Vitess"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Check checksum consistency across servers:\n// SELECT @@global.binlog_checksum; -- must match on primary and replicas","typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"can't strip checksum from binlog event\") {\n    // stop the vstream, verify binlog integrity, restart to re-read FORMAT_DESCRIPTION_EVENT\n}","preventionTips":["Keep binlog_checksum uniform across the topology","Restart vstreams after changing checksum settings","Verify binlog integrity after storage/disk incidents"],"tags":["binlog","checksum","corruption","vstreamer"],"backgroundTag":"binlog-checksum-mismatch","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}