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

  1. Check the logged event data for truncation or garbage bytes
  2. Confirm source MySQL flavor/version is supported by the vitess binlog parser
  3. Re-establish the stream from a clean position or fresh backup of the binlogs
  4. 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

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


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/62f00e6d8cac9f0d. Report an issue: GitHub.