{"record":{"id":"852c4c5b14b530f4","repo":"AlexxIT/go2rtc","slug":"dtls-client-handshake-failed-w","errorCode":null,"errorMessage":"dtls: client handshake failed: %w","messagePattern":"dtls: client handshake failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/tutk/dtls/conn_dtls.go","lineNumber":569,"sourceCode":"}\n\nfunc (c *DTLSConn) discoDoneCC51() error {\n\t_, err := c.WriteAndWait(c.msgDiscoCC51(2, c.ticket, false), func(res []byte) bool {\n\t\tif len(res) < packetSizeCC51 || string(res[:2]) != magicCC51 {\n\t\t\treturn false\n\t\t}\n\t\tcmd := binary.LittleEndian.Uint16(res[4:])\n\t\tdir := binary.LittleEndian.Uint16(res[8:])\n\t\tseq := binary.LittleEndian.Uint16(res[12:])\n\t\treturn cmd == cmdDiscoCC51 && dir == 0xFFFF && seq == 3\n\t})\n\treturn err\n}\n\nfunc (c *DTLSConn) connect() error {\n\tconn, err := NewDTLSClient(c.ctx, iotcChannelMain, c.addr, c.WriteDTLS, c.clientBuf, c.psk)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dtls: client handshake failed: %w\", err)\n\t}\n\n\tc.mu.Lock()\n\tc.clientConn = conn\n\tc.mu.Unlock()\n\n\tif c.verbose {\n\t\tfmt.Printf(\"[DTLS] Client handshake complete on channel %d\\n\", iotcChannelMain)\n\t}\n\n\treturn nil\n}\n\nfunc (c *DTLSConn) worker() {\n\tdefer c.wg.Done()\n\n\tbuf := make([]byte, 2048)\n","sourceCodeStart":551,"sourceCodeEnd":587,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/tutk/dtls/conn_dtls.go#L551-L587","documentation":"connect performs the client-side PSK DTLS handshake on the main channel and wraps any NewDTLSClient failure with this error. It means the DTLS client handshake with the camera did not complete, so the session cannot be established.","triggerScenarios":"DialDTLS -> connect when NewDTLSServer/NewDTLSClient handshake fails: wrong PSK, handshake timeouts, UDP packet loss, or DTLS alert from the camera.","commonSituations":"PSK mismatch after a device password change; lossy WAN link dropping handshake flights; camera firmware with non-standard DTLS parameters; NAT rebinding mid-handshake.","solutions":["Verify the PSK/credentials for the device are current","Retry the dial — handshake failures over UDP are often transient","Enable verbose DTLS logging to find the failing flight","Check MTU/fragmentation issues on the path (handshake packets exceeding MTU)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if psk == nil || len(psk) == 0 {\n\treturn fmt.Errorf(\"missing DTLS PSK for device\")\n}","typeGuard":null,"tryCatchPattern":"conn, err := dtls.DialDTLS(ctx, uid, psk)\nif err != nil {\n\tif strings.Contains(err.Error(), \"client handshake failed\") {\n\t\t// transient UDP loss is common: re-dial with backoff\n\t}\n\treturn err\n}","preventionTips":["Refresh PSK after any device credential change","Retry dial with exponential backoff for UDP handshake flakiness","Check path MTU if handshake repeatedly fails at a specific flight","Enable verbose DTLS logs when diagnosing"],"tags":["dtls","handshake","psk","network"],"backgroundTag":"handshake-failed","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"}