vitessio/vitess · error
can't get query from binlog event: %v, event data: %#v
Error message
can't get query from binlog event: %v, event data: %#v
What it means
parseEvents reads a QUERY_EVENT and calls ev.Query(format) to extract the query string. If the event body cannot be decoded (bad lengths, truncated data, incompatible format description), the streamer stops and returns this error with the raw event bytes.
Source
Thrown at go/vt/binlog/binlog_streamer.go:402
Sql: fmt.Appendf(nil, "SET %s=%d", mysql.IntVarNames[typ], value),
},
})
case ev.IsRand(): // RAND_EVENT
seed1, seed2, err := ev.Rand(format)
if err != nil {
return pos, fmt.Errorf("can't parse RAND_EVENT: %v, event data: %#v", err, ev)
}
statements = append(statements, FullBinlogStatement{
Statement: &binlogdatapb.BinlogTransaction_Statement{
Category: binlogdatapb.BinlogTransaction_Statement_BL_SET,
Sql: fmt.Appendf(nil, "SET @@RAND_SEED1=%d, @@RAND_SEED2=%d", seed1, seed2),
},
})
case ev.IsQuery(): // QUERY_EVENT
// Extract the query string and group into transactions.
q, err := ev.Query(format)
if err != nil {
return pos, fmt.Errorf("can't get query from binlog event: %v, event data: %#v", err, ev)
}
switch cat := getStatementCategory(q.SQL); cat {
case binlogdatapb.BinlogTransaction_Statement_BL_BEGIN:
begin()
case binlogdatapb.BinlogTransaction_Statement_BL_ROLLBACK:
// Rollbacks are possible under some circumstances. Since the stream
// client keeps track of its replication position by updating the set
// of GTIDs it's seen, we must commit an empty transaction so the client
// can update its position.
statements = nil //nolint:prealloc
fallthrough
case binlogdatapb.BinlogTransaction_Statement_BL_COMMIT:
if err = commit(ev.Timestamp()); err != nil {
return pos, err
}
default: // BL_DDL, BL_SET, BL_INSERT, BL_UPDATE, BL_DELETE, BL_UNRECOGNIZED
if q.Database != "" && q.Database != bls.cp.DBName() {
// Skip cross-db statements.View on GitHub (pinned to 01a25a7d17)
Solutions
- Check the logged event data for truncation or garbage bytes
- Confirm source MySQL flavor/version is supported by the vitess binlog parser
- Re-establish the stream from a clean position or fresh backup of the binlogs
- If running a custom/test streamer, fix the event payload it emits (correct query header and body)
Defensive patterns
Strategy: try-catch
Validate before calling
// sanity-check the binlog before streaming: // mysqlbinlog <file> > /dev/null && echo ok
Try / catch
err := streamer.Stream(ctx, signals)
if err != nil && strings.Contains(err.Error(), "can't get query from binlog event") {
// inspect position returned, validate file, restart from clean GTID
} Prevention
- Use mysqlbinlog to validate binlogs before use
- Never mix MariaDB and MySQL binlogs in one stream
- Avoid copying binlogs with rsync during writes
- Stream from a GTID at transaction boundaries
When it happens
Trigger: A QUERY_EVENT in the binlog stream fails to decode inside parseEvents, e.g. truncated payload, corrupt log file, or format-description mismatch; Stream aborts at that position.
Common situations: Binlog files damaged in transit or on disk, mixing binlogs from different MySQL versions/flavors (MariaDB vs MySQL) that vitess cannot parse, or a synthetic binlog streamer (test/file streamer) emitting malformed events.
Related errors
- can't parse RAND_EVENT: %v, event data: %#v
- stream error @ (including the GTID we failed to process) %v:
- send reply error: %v
- SBR mode unsupported for streaming: %s
- GetPreviousGTIDs: previous GTIDs not found
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/62f00e6d8cac9f0d.
Report an issue: GitHub.