{"record":{"id":"8e01cf8a9f666102","repo":"AlexxIT/go2rtc","slug":"wyze-k10002-failed-w","errorCode":null,"errorMessage":"wyze: K10002 failed: %w","messagePattern":"wyze: K10002 failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wyze/client.go","lineNumber":355,"sourceCode":"\tdata, err := c.conn.WriteAndWaitIOCtrl(c.buildK10000(), c.matchHL(KCmdChallenge), 5*time.Second)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"wyze: K10001 failed: %w\", err)\n\t}\n\n\thlData := c.extractHL(data)\n\tchallenge, status, err := c.parseK10001(hlData)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"wyze: K10001 parse failed: %w\", err)\n\t}\n\n\tif c.verbose {\n\t\tfmt.Printf(\"[Wyze] K10001 challenge received, status=%d\\n\", status)\n\t}\n\n\t// Step 2: K10002 -> K10003 (Auth)\n\tdata, err = c.conn.WriteAndWaitIOCtrl(c.buildK10002(challenge, status), c.matchHL(KCmdAuthResult), 5*time.Second)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"wyze: K10002 failed: %w\", err)\n\t}\n\thlData = c.extractHL(data)\n\n\t// Parse K10003 response\n\tauthResp, err := c.parseK10003(hlData)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"wyze: K10003 parse failed: %w\", err)\n\t}\n\n\tif c.verbose && authResp != nil {\n\t\tif jsonBytes, err := json.MarshalIndent(authResp, \"\", \"  \"); err == nil {\n\t\t\tfmt.Printf(\"[Wyze] K10003 response:\\n%s\\n\", jsonBytes)\n\t\t}\n\t}\n\n\t// Extract audio capability from cameraInfo\n\tif authResp != nil && authResp.CameraInfo != nil {\n\t\tif channelResult, ok := authResp.CameraInfo[\"channelRequestResult\"].(map[string]any); ok {","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/wyze/client.go#L337-L373","documentation":"doKAuth step 2 sends the K10002 auth request (challenge + status) and waits for the K10003 result via WriteAndWaitIOCtrl (5s). Failure of the write/IO-ctrl exchange (timeout, dead socket) is wrapped as \"wyze: K10002 failed\".","triggerScenarios":"Camera does not reply with KCmdAuthResult within 5 seconds; underlying DTLS socket closed between K10001 and K10002; camera rejected the session before evaluating credentials.","commonSituations":"Flaky Wi-Fi dropping the tunnel mid-handshake; camera busy/streaming to another client and slow to respond; camera firmware stalling the auth exchange.","solutions":["Retry the full Dial sequence with backoff — the handshake is session-scoped.","Verify credentials are current; repeated K-stage timeouts can precede auth rejection elsewhere.","Check that nothing else is closing the client/connection concurrently (race on the socket).","Ensure network stability; timeouts here usually indicate packet loss to the camera."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := client.Dial(); err != nil {\n    if strings.Contains(err.Error(), \"K10002 failed\") {\n        time.Sleep(time.Second)\n        err = client.Dial() // restart the whole handshake\n    }\n    if err != nil {\n        return err\n    }\n}","preventionTips":["Retry the complete Dial sequence with backoff","Ensure the network path to the camera is stable before auth","Don't Close the client concurrently during handshake"],"tags":["go","iot","authentication","timeout"],"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"}