AlexxIT/go2rtc · error

multitrans: talkback failed

Error message

multitrans: talkback failed: ${res.Status}

What it means

The final leg of the multitrans handshake, openTalkChannel, sends the talkback request and requires a 200 OK response. Any other status means the talk channel could not be opened; the server's status line is embedded in the error. Note this is distinct from a 200 body containing a non-zero error_code, which raises 'talkback error' instead.

Solutions

  1. Re-run Dial from scratch to obtain a fresh session, then retry.
  2. Ensure no other client/process is holding the device's talk session concurrently.
  3. Verify the device account has permission for audio talkback (not just viewing).
  4. Check device logs and firmware version; upgrade if talkback endpoint behavior changed.

Example fix

// before
err := client.Dial(ctx) // one-shot; session may expire on retry loops

// after
for i := 0; i < 3; i++ {
    if err := client.Dial(ctx); err == nil { break }
    time.Sleep(time.Second) // re-handshake to get a fresh session
}
Defensive patterns

Strategy: retry

Try / catch

var err error
for attempt := 0; attempt < 3; attempt++ {
    if err = client.Dial(ctx); err == nil { break }
    if strings.Contains(err.Error(), "talkback failed") {
        time.Sleep(time.Duration(1<<attempt) * time.Second) // fresh session each try
        continue
    }
    return err
}

Prevention

When it happens

Trigger: Dial -> handshake -> openTalkChannel; the talkback HTTP request returns a status other than 200 (e.g. 401, 403, 500).

Common situations: Session expired between auth and talkback (another client took the session); device limits concurrent talk sessions; insufficient user permissions for two-way audio; device rebooted mid-handshake.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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

Appendix: source

Thrown at pkg/multitrans/client.go:180

}

func (c *Client) openTalkChannel(uri, session string) error {
	payload := `{"type":"request","seq":0,"params":{"method":"get","talk":{"mode":"full_duplex"}}}`

	data := fmt.Sprintf("MULTITRANS %s RTSP/1.0\r\nCSeq: 2\r\nSession: %s\r\nContent-Type: application/json\r\nContent-Length: %d\r\n\r\n%s",
		uri, session, len(payload), payload)

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

	res, err := tcp.ReadResponse(c.rd)
	if err != nil {
		return err
	}

	if res.StatusCode != http.StatusOK {
		return errors.New("multitrans: talkback failed: " + res.Status)
	}

	// Python checks for "error_code":0 in body.
	if !bytes.Contains(res.Body, []byte(`"error_code":0`)) {
		return fmt.Errorf("multitrans: talkback error: %s", string(res.Body))
	}

	return nil
}

func (c *Client) GetTrack(media *core.Media, codec *core.Codec) (*core.Receiver, error) {
	return nil, core.ErrCantGetTrack
}

func (c *Client) Start() error {
	_ = c.closed.Wait()
	return nil
}

View on GitHub (pinned to c245815e75)