AlexxIT/go2rtc · error

rtmp: unknown command:

Error message

rtmp: unknown command: 

What it means

After handling CommandPlay and CommandPublish, the RTMP server's tcpHandle treats any other rtmpConn.Intent as unsupported and returns "rtmp: unknown command: <intent>". The library only implements play and publish for incoming RTMP connections.

Solutions

  1. Use a standard RTMP client that issues only play or publish commands
  2. Update the client library to a conforming RTMP implementation
  3. Inspect the intent value in the error to identify the offending client
  4. If you need more commands, patch the RTMP server handler to support them
Defensive patterns

Strategy: try-catch

Try / catch

// Go
if err := tcpHandle(conn); err != nil {
    if strings.HasPrefix(err.Error(), "rtmp: unknown command") {
        log.Warn().Msg("client sent unsupported RTMP intent; dropping connection")
        conn.Close()
    }
}

Prevention

When it happens

Trigger: An RTMP client sends an intent/command other than play or publish (custom or malformed handshake state), so the switch statement falls through to the default error return at internal/rtmp/rtmp.go:124.

Common situations: Non-standard RTMP clients or fuzzers sending unexpected commands, a client library setting a custom intent value, or protocol-level misbehavior after handshake.

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/cc1be5e36986556d. Report an issue: GitHub.

Appendix: source

Thrown at internal/rtmp/rtmp.go:124

		if err = rtmpConn.WriteStart(); err != nil {
			return err
		}

		prod, err := rtmpConn.Producer()
		if err != nil {
			return err
		}

		stream.AddProducer(prod)

		defer stream.RemoveProducer(prod)

		_ = prod.Start()

		return nil
	}

	return errors.New("rtmp: unknown command: " + rtmpConn.Intent)
}

var log zerolog.Logger

func streamsHandle(url string) (core.Producer, error) {
	return rtmp.DialPlay(url)
}

func streamsConsumerHandle(url string) (core.Consumer, func(), error) {
	cons := flv.NewConsumer()
	run := func() {
		wr, err := rtmp.DialPublish(url, cons)
		if err != nil {
			return
		}
		_, err = cons.WriteTo(wr)
	}

View on GitHub (pinned to c245815e75)