vitessio/vitess · critical

uncaught panic: %v

Error message

uncaught panic: %v

What it means

UpdateStreamImpl.HandlePanic is a deferred recover hook on UpdateStream RPCs. If a streaming handler panics, the panic is logged with a stack trace and converted into this returned error so callers get an RPC error instead of a crashed process.

Source

Thrown at go/vt/binlog/updatestreamctl.go:293

	f := tablesFilterFunc(tables, func(trans *binlogdatapb.BinlogTransaction) error {
		tablesStatements.Add(int64(len(trans.Statements)))
		tablesTransactions.Add(1)
		return callback(trans)
	})
	bls := NewStreamer(updateStream.cp, updateStream.se, charset, pos, 0, f)

	streamCtx, cancel := context.WithCancel(ctx)
	i := updateStream.streams.Add(cancel)
	defer updateStream.streams.Delete(i)

	return bls.Stream(streamCtx)
}

// HandlePanic is part of the UpdateStream interface
func (updateStream *UpdateStreamImpl) HandlePanic(err *error) {
	if x := recover(); x != nil {
		log.Error(fmt.Sprintf("Uncaught panic:\n%v\n%s", x, tb.Stack(4)))
		*err = fmt.Errorf("uncaught panic: %v", x)
	}
}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the preceding 'Uncaught panic:' log line for the panic value and stack trace.
  2. Reproduce the panic with the specific binlog event/query shown and report/fix the underlying nil/edge-case bug.
  3. Update Vitess — many streamer panics are fixed in later releases.
  4. Retry the stream after the process recovers; the stream is terminated by the panic.

Example fix

// before: panics on nil charset
svc.Register... stream(statement.Charset.String())
// after: guard nil
if statement.Charset != nil { ... }
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure stream inputs are non-nil before invoking UpdateStream RPCs
if keyrange == nil || callback == nil {
	return errors.New("keyrange and callback are required")
}

Try / catch

defer func() {
	if r := recover(); r != nil {
		log.Error(fmt.Sprintf("client-side stream panic: %v\n%s", r, debug.Stack()))
		err = fmt.Errorf("uncaught panic: %v", r)
	}
}()
err := updateStream.Stream(ctx, callback)

Prevention

When it happens

Trigger: Any panic inside UpdateStream streaming methods (nil dereference, index out of range, vterrors of unexpected kind) recovered by HandlePanic via defer.

Common situations: Bugs in filter/streamer code triggered by unusual binlog events; concurrent shutdown racing a stream; malformed topo data causing nil maps.

Related errors


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