{"record":{"id":"0c464a25f6f6ed62","repo":"vitessio/vitess","slug":"can-t-strip-checksum-from-binlog-event-v-event","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/binlog/binlog_streamer.go","lineNumber":343,"sourceCode":"\t\t\tcontinue\n\t\t}\n\n\t\t// We can't parse anything until we get a FORMAT_DESCRIPTION_EVENT that\n\t\t// tells us the size of the event header.\n\t\tif format.IsZero() {\n\t\t\t// The only thing that should come before the FORMAT_DESCRIPTION_EVENT\n\t\t\t// is a fake ROTATE_EVENT, which the primary sends to tell us the name\n\t\t\t// of the current log file.\n\t\t\tif ev.IsRotate() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn pos, fmt.Errorf(\"got a real event before FORMAT_DESCRIPTION_EVENT: %#v\", ev)\n\t\t}\n\n\t\t// Strip the checksum, if any. We don't actually verify the checksum, so discard it.\n\t\tev, _, err = ev.StripChecksum(format)\n\t\tif err != nil {\n\t\t\treturn pos, fmt.Errorf(\"can't strip checksum from binlog event: %v, event data: %#v\", err, ev)\n\t\t}\n\n\t\tswitch {\n\t\tcase ev.IsPseudo():\n\t\t\tgtid, _, _, _, err = ev.GTID(format)\n\t\t\tif err != nil {\n\t\t\t\treturn pos, fmt.Errorf(\"can't get GTID from binlog event: %v, event data: %#v\", err, ev)\n\t\t\t}\n\t\t\toldpos := pos\n\t\t\tpos = replication.AppendGTID(pos, gtid)\n\t\t\t// If the event is received outside of a transaction, it must\n\t\t\t// be sent. Otherwise, it will get lost and the targets will go out\n\t\t\t// of sync.\n\t\t\tif autocommit && !pos.Equal(oldpos) {\n\t\t\t\tif err = commit(ev.Timestamp()); err != nil {\n\t\t\t\t\treturn pos, err\n\t\t\t\t}\n\t\t\t}","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/binlog/binlog_streamer.go#L325-L361","documentation":"Before decoding event bodies, parseEvents calls ev.StripChecksum(format) to remove any trailing checksum bytes according to the format-description. If the event length doesn't match the expected layout, stripping fails and the stream aborts. This means the event is inconsistent with the negotiated binlog format.","triggerScenarios":"During Stream/parseEvents, ev.StripChecksum(format) returns an error because the event size doesn't correspond to the format's header/body/checksum layout — e.g. a new FORMAT_DESCRIPTION_EVENT changed checksum settings mid-stream and a subsequent event doesn't fit.","commonSituations":"Binlog checksum setting (binlog_checksum) changed on the server while streaming; corrupted or truncated event bytes; events from mixed MySQL versions after a log rotate.","solutions":["Check if binlog_checksum was changed on the server mid-stream; keep it consistent or restart the stream after changing","Verify the binlog file integrity with mysqlbinlog","Fail over to a replica with intact binlogs and resume from the last good GTID","Ensure all servers in the topology run a supported, consistent MySQL version"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// keep binlog_checksum stable; verify before streaming\n// mysql> SELECT @@global.binlog_checksum; -- don't change mid-stream","typeGuard":null,"tryCatchPattern":"if err := streamer.Stream(ctx); err != nil {\n\tif strings.Contains(err.Error(), \"can't strip checksum\") {\n\t\t// checksum setting changed mid-stream: restart stream, keep binlog_checksum fixed\n\t}\n}","preventionTips":["Never change binlog_checksum while binlog consumers are attached","Keep binlog settings consistent across topology servers","Validate binlogs with mysqlbinlog after config changes"],"tags":["binlog","checksum","corruption"],"backgroundTag":"binlog-checksum-mismatch","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}