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
- Confirm the client is actually connecting with RTMP to this port
- Check for HTTP or RTSP clients hitting the RTMP listener
- 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
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
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)