AlexxIT/go2rtc · error

rtmp: wrong handshake

Error message

rtmp: wrong handshake

What it means

RTMP serverHandshake C0 guard: the first byte read from the client is not RTMP version 3, so the peer is not speaking RTMP (or is sending garbage). The handshake is aborted immediately per spec before S0/S1 are written.

Solutions

  1. Confirm the client is actually connecting with RTMP to this port
  2. Check for HTTP or RTSP clients hitting the RTMP listener
  3. Inspect for TLS bytes — the client may expect rtmps
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at pkg/rtmp/server.go:50 when the library encounters an invalid state.

Common situations: See trigger scenarios.

Understand the failure class


AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07). Data as JSON: /api/errors/1871b6529f26beea. Report an issue: GitHub.

Appendix: source

Thrown at pkg/rtmp/server.go:50

	if err := c.writePacketSize(); err != nil {
		return nil, err
	}

	return c, nil
}

func (c *Conn) serverHandshake() error {
	// based on https://rtmp.veriskope.com/docs/spec/
	_ = c.conn.SetDeadline(time.Now().Add(core.ConnDeadline))

	// read C0
	b := make([]byte, 1)
	if _, err := io.ReadFull(c.rd, b); err != nil {
		return err
	}

	if b[0] != 3 {
		return errors.New("rtmp: wrong handshake")
	}

	// write S0
	if _, err := c.conn.Write([]byte{3}); err != nil {
		return err
	}

	b = make([]byte, 1536)

	// write S1
	tsS1 := nowMS()
	binary.BigEndian.PutUint32(b, tsS1)
	binary.BigEndian.PutUint32(b[4:], 0)
	_, _ = rand.Read(b[8:])
	if _, err := c.conn.Write(b); err != nil {
		return err
	}

View on GitHub (pinned to c245815e75)