vitessio/vitess · error
filter rules are not supported for SBR replication: %v
Error message
filter rules are not supported for SBR replication: %v
What it means
VReplication supports row-based replication (RBR) filtering via the workflow's Filter rules. When the source stream is statement-based replication (SBR) events (VEventType_STMT), row-filter rules cannot be applied, so vplayer refuses the event and errors out rather than silently replicating unfiltered or incorrectly filtered statements.
Source
Thrown at go/vt/vttablet/tabletmanager/vreplication/vplayer.go:360
}
return err
}
}
// applyStmtEvent applies an actual DML statement received from the source, directly onto the backend database
func (vp *vplayer) applyStmtEvent(ctx context.Context, event *binlogdatapb.VEvent) error {
sql := event.Statement
if sql == "" {
sql = event.Dml
}
if event.Type == binlogdatapb.VEventType_SAVEPOINT || vp.canAcceptStmtEvents {
start := time.Now()
_, err := vp.query(ctx, sql)
vp.vr.stats.QueryTimings.Record(vp.phase, start)
vp.vr.stats.QueryCount.Add(vp.phase, 1)
return err
}
return fmt.Errorf("filter rules are not supported for SBR replication: %v", vp.vr.source.Filter.GetRules())
}
// bulkApplicableShapes scans a row event's changes and reports whether they
// are all delete-shaped (Before image only) or all insert-shaped (After image
// only). A single event can mix shapes: when only one side of an update passes
// the source vstreamer's workflow filter (e.g. a sharding-key update that
// moves rows across an in_keyrange boundary), only that side's image is
// emitted, so one multi-row UPDATE can yield insert-shaped, delete-shaped and
// update-shaped changes in the same event. The bulk DELETE/INSERT statements
// assume a homogeneous event, so a mixed event must be applied per-change.
// A change with no images at all (nil, or present but empty) is malformed --
// the vstreamer never produces one -- and is rejected with an error rather
// than being routed to either apply path: the per-change path would
// dereference a nil change and silently treat an empty one as a no-op.
// The scan visits every change, even once the event is already known not to
// be bulk-applicable, so a malformed entry is detected regardless of its
// position.
func bulkApplicableShapes(tableName string, rowChanges []*binlogdatapb.RowChange) (deletesOnly, insertsOnly bool, err error) {View on GitHub (pinned to 01a25a7d17)
Solutions
- Set binlog_format=ROW on the source MySQL cluster and restart replication before/while vstreaming
- Verify the source's binlog format with SHOW VARIABLES LIKE 'binlog_format' and ensure it persists in my.cnf
- Re-create/restart the vreplication workflow after switching the source to ROW format
- If you genuinely need SBR with filters, remove filter rules or redesign the workflow — the combination is unsupported
Example fix
// before (source my.cnf) binlog_format = STATEMENT // after binlog_format = ROW
Defensive patterns
Strategy: validation
Validate before calling
// Verify the source uses ROW binlog format before starting a filtered workflow
row, err := db.Query("SHOW VARIABLES LIKE 'binlog_format'")
// fail fast if value != "ROW" Try / catch
if err != nil && strings.Contains(err.Error(), "filter rules are not supported for SBR") {
// switch source to binlog_format=ROW, then restart the workflow
} Prevention
- Always set binlog_format=ROW on sources used for VReplication with filter rules
- Persist binlog_format in my.cnf so restarts don't revert to STATEMENT/MIXED
- Avoid MIXED format, which can emit statement events for non-deterministic statements
- Validate source config as part of workflow preflight checks
When it happens
Trigger: applyStmtEvent is reached with vp.vr.source.Filter containing rules while the source binlog stream is in statement-based mode (binlog_format=STATEMENT or MIXED producing statement events on the vstream).
Common situations: Source MySQL cluster configured with binlog_format=STATEMENT or MIXED; source downgrade or a MySQL flavor that reverted to SBR; workflow set up expecting RBR but source not in ROW format.
Related errors
- rule %v does not have a select expression in vreplication
- unexpected rule in vreplication: %v
- table %s not found in schema
- more than one target for source table %s: %s and %s
- unsupported multiple keyspace_id expressions: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/23249282c67c62df.
Report an issue: GitHub.