vitessio/vitess · error
first event from binlog %v is not valid
Error message
first event from binlog %v is not valid
What it means
After sending ComBinlogDump for a candidate file, getBinlogTimeStamp validates that the very first event returned is a valid binlog event (event.IsValid()). If it is not, the file's stream cannot be trusted to find a timestamp, and this error naming the file is returned. This usually indicates the file is truncated, not a real binlog, or the server sent something unexpected.
Source
Thrown at go/vt/binlog/binlog_connection.go:282
if err != nil {
return 0, err
}
defer conn.Close()
if err := conn.WriteComBinlogDump(bc.serverID, filename, 4, 0); err != nil {
return 0, fmt.Errorf("failed to send the ComBinlogDump command: %v", err)
}
// Get the first event to get its timestamp. We skip
// events that don't have timestamps (although it seems
// most do anyway).
for {
event, err := conn.ReadBinlogEvent()
if err != nil {
return 0, fmt.Errorf("error reading binlog event %v: %v", filename, err)
}
if !event.IsValid() {
return 0, fmt.Errorf("first event from binlog %v is not valid", filename)
}
if ts := event.Timestamp(); ts > 0 {
return int64(ts), nil
}
}
}
// Close closes the binlog connection, which also signals an ongoing dump
// started with StartBinlogDump() to stop and close its BinlogEvent channel.
// The ID for the binlog connection is recycled back into the pool.
func (bc *BinlogConnection) Close() {
if bc.Conn != nil {
log.Info("closing binlog socket to unblock reads")
bc.Conn.Close()
// bc.cancel is set at the beginning of the StartBinlogDump*
// methods. If we error out before then, it's nil.
// Note we also may error out before adding 1 to bc.wg,View on GitHub (pinned to 01a25a7d17)
Solutions
- Verify the named file's integrity on the primary with mysqlbinlog; if truncated, stop serving it (or restore from backup).
- Ensure the Vitess binary and MySQL server versions are compatible for replication protocol parsing.
- Let findFileBeforeTimestamp proceed to an older intact binlog file if the requested timestamp allows it.
- Check binlog_expire_logs_seconds / PURGE BINARY LOGS activity so files are not being removed or truncated during the scan.
Defensive patterns
Strategy: fallback
Validate before calling
// verify file integrity before probing // mysqlbinlog binlog.000123 > /dev/null && echo OK || echo CORRUPT
Try / catch
if err != nil && strings.Contains(err.Error(), "is not valid") {
// fall back to the next older binlog file, or re-seed from a backup
} Prevention
- Enable binlog checksums and verify files after any crash recovery.
- Don't truncate or partially copy binlogs during storage moves.
- Watch binlog expiration so files aren't purged mid-scan.
- Keep replica Vitess/MySQL versions in supported combinations.
When it happens
Trigger: getBinlogTimeStamp reads a first event that fails IsValid() — typically a zero-length/garbage first packet from a truncated or partially purged binlog file, or a server-side error delivered as a non-event packet.
Common situations: Binlog files truncated by a primary crash; manual copying/rsyncing of binlogs producing incomplete files; version-mismatched replica reading binlogs written by an incompatible server; relay-style proxies injecting unexpected frames.
Related errors
- error reading binlog event %v: %v
- GetPreviousGTIDs: previous GTIDs not found
- startPos.GTIDSet is wrong type - expected filePosGTID, got:
- failed to set @source_binlog_checksum=@@global.binlog_checks
- failed to get primary position: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/c2d1c1822e345ee7.
Report an issue: GitHub.