AlexxIT/go2rtc · error

timeout waiting for response

Error message

timeout waiting for response

What it means

WriteAndWaitIOCtrl sends an IO control command and waits for a matching response; if no response satisfying the match predicate arrives before the timer fires, it returns this error. It means the camera acknowledged (or did not) but never produced the expected reply within the timeout window.

Solutions

  1. Increase the response timeout for high-latency links
  2. Log received frames during the wait to see what the camera actually replies with
  3. Verify the match predicate matches your camera firmware's response layout
  4. Retry the command once; transient camera busyness is common

Example fix

// before
data, err := conn.WriteAndWaitIOCtrl(cmd, payload, matcher)
// after
var data []byte
for attempt := 0; attempt < 2; attempt++ {
	data, err = conn.WriteAndWaitIOCtrl(cmd, payload, matcher)
	if err == nil {
		break
	}
	time.Sleep(300 * time.Millisecond)
}
Defensive patterns

Strategy: retry

Try / catch

data, err := conn.WriteAndWaitIOCtrl(cmd, payload, match)
if err != nil {
	if errors.Is(err, os.ErrDeadlineExceeded) || strings.Contains(err.Error(), "timeout") {
		// retry once with backoff before failing the caller
	}
}

Prevention

When it happens

Trigger: Called from SetResolution, StartVideo, StartAudio, StartIntercom, doKAuth when the camera's IOCTRL response never matches the predicate before the timer expires — device slow, offline, or replying with an unexpected payload.

Common situations: Busy camera ignoring IO control during heavy load; WAN latency exceeding the timeout; firmware returning a different response format than the matcher expects; camera connected but session degraded.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at pkg/tutk/dtls/conn_dtls.go:443

	timer := time.NewTimer(timeout)
	defer timer.Stop()

	for {
		select {
		case data, ok := <-c.rawCmd:
			if !ok {
				return nil, io.EOF
			}

			ack := c.msgACK()
			c.clientConn.Write(ack)

			if match(data) {
				return data, nil
			}
		case <-timer.C:
			return nil, fmt.Errorf("timeout waiting for response")
		}
	}
}

func (c *DTLSConn) HasTwoWayStreaming() bool {
	return c.hasTwoWayStreaming
}

func (c *DTLSConn) IsBackchannelReady() bool {
	c.mu.RLock()
	defer c.mu.RUnlock()
	return c.serverConn != nil
}

func (c *DTLSConn) RemoteAddr() *net.UDPAddr {
	return c.addr
}

View on GitHub (pinned to c245815e75)