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

  1. Only call GetTrack on Conns operating as ModeActiveProducer or ModePassiveConsumer; check c.mode before calling.
  2. If you need to send media, use the Senders/GetTrack-for-sending API appropriate to the mode instead.
  3. 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

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


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)