{"record":{"id":"0aa140dc7b2d4219","repo":"AlexxIT/go2rtc","slug":"hap-verifyserverauthenticator","errorCode":null,"errorMessage":"hap: VerifyServerAuthenticator","messagePattern":"hap: VerifyServerAuthenticator","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/hap/client_pairing.go","lineNumber":173,"sourceCode":"\t\tProof string `tlv8:\"4\"` // server proof\n\t\tState byte   `tlv8:\"6\"`\n\t\tError byte   `tlv8:\"7\"`\n\n\t\tEncryptedData string `tlv8:\"5\"` // skip EncryptedData validation (for MFi devices)\n\t}\n\tif err = tlv8.UnmarshalReader(res.Body, res.ContentLength, &plainM4); err != nil {\n\t\treturn\n\t}\n\tif plainM4.State != StateM4 {\n\t\treturn newResponseError(plainM3, plainM4)\n\t}\n\tif plainM4.Error != 0 {\n\t\treturn newPairingError(plainM4.Error)\n\t}\n\n\t// STEP M4. Verify response\n\tif !session.VerifyServerAuthenticator([]byte(plainM4.Proof)) {\n\t\treturn errors.New(\"hap: VerifyServerAuthenticator\")\n\t}\n\n\t// STEP M5. Generate signature\n\tlocalSign, err := hkdf.Sha512(\n\t\tsessionShared, \"Pair-Setup-Controller-Sign-Salt\", \"Pair-Setup-Controller-Sign-Info\",\n\t)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tb := Append(localSign, c.ClientID, c.ClientPublic())\n\tsignature, err := ed25519.Signature(c.ClientPrivate, b)\n\tif err != nil {\n\t\treturn\n\t}\n\n\t// STEP M5. Generate payload\n\tplainM5 := struct {","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/hap/client_pairing.go#L155-L191","documentation":"In Pair's STEP M4, the client verifies the server's SRP proof (M4) with session.VerifyServerAuthenticator. Failure means the accessory did not prove it knows the same SRP secret derived from the setup PIN — i.e. the PIN is wrong, the device is not in pairing mode, or the pairing handshake desynchronized.","triggerScenarios":"Typing an incorrect setup code (the 8-digit PIN on the device label); the accessory is already paired to another controller and rejects a new pairing; M1-M3 exchange corrupted by a flaky connection; device firmware rejecting pairing while not in allow-pairing state.","commonSituations":"User misreading the PIN (ambiguous characters, confusing 0/O or 1/I); attempting to pair a camera that was already paired from a phone; pairing immediately after power-on before the HAP server accepts pairings.","solutions":["Re-enter the setup PIN carefully (8 digits, from the device label/HomeKit setup card) and retry Pair.","Confirm the accessory accepts new pairings: remove the device from any other HomeKit controller first.","Power-cycle the accessory and start a fresh Pair session (new SRP session) — never reuse a half-finished session.","If the device consistently fails M4 with the correct PIN, factory-reset it and pair again."],"exampleFix":"// before: single Pair attempt with a possibly mistyped PIN\nerr := client.Pair(\"0314520\")\n// after: normalize the PIN (digits only) and surface a clear message on failure\npin := strings.ReplaceAll(cfg.PIN, \"-\", \"\")\nif len(pin) != 8 { return errors.New(\"setup PIN must be 8 digits\") }\nif err := client.Pair(pin); err != nil {\n    if strings.Contains(err.Error(), \"VerifyServerAuthenticator\") {\n        return errors.New(\"pairing rejected: wrong setup PIN or device already paired\")\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"pin := strings.ReplaceAll(setupCode, \"-\", \"\")\nif len(pin) != 8 {\n    return errors.New(\"setup PIN must be exactly 8 digits\")\n}","typeGuard":null,"tryCatchPattern":"if err := client.Pair(pin); err != nil {\n    if strings.Contains(err.Error(), \"VerifyServerAuthenticator\") {\n        // wrong PIN, device already paired, or not in pairing mode:\n        // re-prompt the user and start a fresh Pair session\n        return errors.New(\"pairing rejected: check the setup PIN and that the device accepts pairings\")\n    }\n    return err\n}","preventionTips":["Normalize the PIN (strip dashes/spaces) and validate 8 digits before Pair.","Remove the accessory from other HomeKit controllers before pairing a new client.","Always start a fresh session per attempt — never reuse a half-finished SRP exchange."],"tags":["hap","srp","pairing","pin","authentication"],"backgroundTag":"signature-verification-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"}