{"record":{"id":"d04dc747e533bc02","repo":"AlexxIT/go2rtc","slug":"timeout-waiting-for-response","errorCode":null,"errorMessage":"timeout waiting for response","messagePattern":"timeout waiting for response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/tutk/dtls/conn_dtls.go","lineNumber":443,"sourceCode":"\n\ttimer := time.NewTimer(timeout)\n\tdefer timer.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase data, ok := <-c.rawCmd:\n\t\t\tif !ok {\n\t\t\t\treturn nil, io.EOF\n\t\t\t}\n\n\t\t\tack := c.msgACK()\n\t\t\tc.clientConn.Write(ack)\n\n\t\t\tif match(data) {\n\t\t\t\treturn data, nil\n\t\t\t}\n\t\tcase <-timer.C:\n\t\t\treturn nil, fmt.Errorf(\"timeout waiting for response\")\n\t\t}\n\t}\n}\n\nfunc (c *DTLSConn) HasTwoWayStreaming() bool {\n\treturn c.hasTwoWayStreaming\n}\n\nfunc (c *DTLSConn) IsBackchannelReady() bool {\n\tc.mu.RLock()\n\tdefer c.mu.RUnlock()\n\treturn c.serverConn != nil\n}\n\nfunc (c *DTLSConn) RemoteAddr() *net.UDPAddr {\n\treturn c.addr\n}\n","sourceCodeStart":425,"sourceCodeEnd":461,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/tutk/dtls/conn_dtls.go#L425-L461","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Increase the response timeout for high-latency links","Log received frames during the wait to see what the camera actually replies with","Verify the match predicate matches your camera firmware's response layout","Retry the command once; transient camera busyness is common"],"exampleFix":"// before\ndata, err := conn.WriteAndWaitIOCtrl(cmd, payload, matcher)\n// after\nvar data []byte\nfor attempt := 0; attempt < 2; attempt++ {\n\tdata, err = conn.WriteAndWaitIOCtrl(cmd, payload, matcher)\n\tif err == nil {\n\t\tbreak\n\t}\n\ttime.Sleep(300 * time.Millisecond)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"data, err := conn.WriteAndWaitIOCtrl(cmd, payload, match)\nif err != nil {\n\tif errors.Is(err, os.ErrDeadlineExceeded) || strings.Contains(err.Error(), \"timeout\") {\n\t\t// retry once with backoff before failing the caller\n\t}\n}","preventionTips":["Retry transient IO control timeouts once or twice","Raise timeouts for WAN/high-latency deployments","Log unmatched responses to detect firmware format drift","Check camera load/health when timeouts repeat"],"tags":["timeout","ioctrl","camera","control"],"backgroundTag":"request-timeout","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}