{"record":{"id":"8472eceb2e78d108","repo":"AlexxIT/go2rtc","slug":"hap-verifyclientauthenticator","errorCode":null,"errorMessage":"hap: VerifyClientAuthenticator","messagePattern":"hap: VerifyClientAuthenticator","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/hap/server.go","lineNumber":113,"sourceCode":"\t\tPublicKey string `tlv8:\"3\"`\n\t\tProof     string `tlv8:\"4\"`\n\t}\n\tif err = tlv8.UnmarshalReader(req.Body, req.ContentLength, &plainM3); err != nil {\n\t\treturn\n\t}\n\tif plainM3.State != StateM3 {\n\t\terr = newRequestError(plainM3)\n\t\treturn\n\t}\n\n\t// important to compute key before verify client\n\tsessionShared, err := session.ComputeKey([]byte(plainM3.PublicKey))\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif !session.VerifyClientAuthenticator([]byte(plainM3.Proof)) {\n\t\terr = errors.New(\"hap: VerifyClientAuthenticator\")\n\t\treturn\n\t}\n\n\tproof := session.ComputeAuthenticator([]byte(plainM3.Proof)) // server proof\n\n\t// STEP 4. Response to iPhone\n\tpayloadM4 := struct {\n\t\tState byte   `tlv8:\"6\"`\n\t\tProof string `tlv8:\"4\"`\n\t}{\n\t\tState: StateM4,\n\t\tProof: string(proof),\n\t}\n\tif body, err = tlv8.Marshal(payloadM4); err != nil {\n\t\treturn\n\t}\n\tif err = WriteResponse(rw.Writer, http.StatusOK, MimeTLV8, body); err != nil {\n\t\treturn","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/hap/server.go#L95-L131","documentation":"Raised during HomeKit pair-setup M3 when the accessory fails to verify the client's authenticator: the proof in TLV field 4 of the M3 request does not match the value expected from the SRP-verified shared secret, so the pairing partner is deemed unauthenticated.","triggerScenarios":"Thrown at pkg/hap/server.go:113 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Verify the SRP session state (verifier, salt, shared secret) is consistent across M1/M2/M3 of the same pairing attempt","Confirm the client proof was computed over the correct transcript (PublicKey of M3 included) with the same hash and key derivation as the server","Discard stale session state and restart pairing from M1 if the session was partially completed or reused"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}