AlexxIT/go2rtc · error
rtsp: wrong mode for GetTrack
Error message
rtsp: wrong mode for GetTrack
What it means
GetTrack on an RTSP producer Conn only supports two modes: ModeActiveProducer (client fetches media via SETUP/PLAY) and ModePassiveConsumer (backchannel receiver). If the connection was created in any other mode (e.g. ModePassiveProducer or ModeActiveConsumer), the mode's consumers use Senders, not Receivers, so requesting a receive track is an invalid operation and this error is returned.
Solutions
- Only call GetTrack on Conns operating as ModeActiveProducer or ModePassiveConsumer; check c.mode before calling.
- If you need to send media, use the Senders/GetTrack-for-sending API appropriate to the mode instead.
- Fix how the Conn is created so it uses the intended mode (ModeActiveProducer for pulling an RTSP stream).
Example fix
// before
track, err := conn.GetTrack(media, codec) // conn.mode == ModePassiveProducer
// after
if conn.Mode == core.ModeActiveProducer || conn.Mode == core.ModePassiveConsumer {
track, err := conn.GetTrack(media, codec)
} Defensive patterns
Strategy: validation
Validate before calling
func canGetTrack(mode core.Mode) bool {
return mode == core.ModeActiveProducer || mode == core.ModePassiveConsumer
}
if !canGetTrack(conn.Mode) {
return errors.New("GetTrack not supported for this connection mode")
} Type guard
func isReceiverMode(mode core.Mode) bool {
return mode == core.ModeActiveProducer || mode == core.ModePassiveConsumer
} Try / catch
track, err := conn.GetTrack(media, codec)
if err != nil {
if strings.Contains(err.Error(), "wrong mode for GetTrack") {
// fall back to the sending-side API for this mode
}
} Prevention
- Know the Conn role (pull vs publish) before touching tracks.
- Expose c.mode via a getter and branch consumer/producer logic on it.
- Add unit tests covering each core.Mode against the track APIs.
When it happens
Trigger: Calling GetTrack(media, codec) on a Conn whose c.mode is neither core.ModeActiveProducer nor core.ModePassiveConsumer — for example calling GetTrack on a connection built as a passive producer (server-side publishing) or active consumer, where pulling incoming media is not applicable.
Common situations: Mixing up consumer/producer APIs: using a producer-side Conn (one publishing to go2rtc, e.g. from an RTSP server session) and then trying to read tracks from it; creating the Conn with the wrong core.Mode; refactoring code that reused a consumer Conn as a producer.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- start from wrong mode
- start from CONN state
- exec: rtsp module disabled
- exec: timeout
- producer without tracks
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/7f0ff93c115e56b6.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/rtsp/producer.go:43
case core.ModeActiveProducer:
if c.state == StatePlay {
if err := c.Reconnect(); err != nil {
return nil, err
}
}
var err error
channel, err = c.SetupMedia(media)
if err != nil {
return nil, err
}
c.state = StateSetup
case core.ModePassiveConsumer:
// Backchannel
channel = byte(len(c.Senders)) * 2
default:
return nil, errors.New("rtsp: wrong mode for GetTrack")
}
track := core.NewReceiver(media, codec)
track.ID = channel
c.Receivers = append(c.Receivers, track)
return track, nil
}
func (c *Conn) Start() (err error) {
core.Assert(c.mode == core.ModeActiveProducer || c.mode == core.ModePassiveProducer)
for {
ok := false
c.stateMu.Lock()
switch c.state {
case StateNone:View on GitHub (pinned to c245815e75)