AlexxIT/go2rtc · error
hap: VerifyServerAuthenticator
Error message
hap: VerifyServerAuthenticator
What it means
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.
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.
Example fix
// before: single Pair attempt with a possibly mistyped PIN
err := client.Pair("0314520")
// after: normalize the PIN (digits only) and surface a clear message on failure
pin := strings.ReplaceAll(cfg.PIN, "-", "")
if len(pin) != 8 { return errors.New("setup PIN must be 8 digits") }
if err := client.Pair(pin); err != nil {
if strings.Contains(err.Error(), "VerifyServerAuthenticator") {
return errors.New("pairing rejected: wrong setup PIN or device already paired")
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
pin := strings.ReplaceAll(setupCode, "-", "")
if len(pin) != 8 {
return errors.New("setup PIN must be exactly 8 digits")
} Try / catch
if err := client.Pair(pin); err != nil {
if strings.Contains(err.Error(), "VerifyServerAuthenticator") {
// wrong PIN, device already paired, or not in pairing mode:
// re-prompt the user and start a fresh Pair session
return errors.New("pairing rejected: check the setup PIN and that the device accepts pairings")
}
return err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- hap: can't dial witout client_id or client_private
- hap: ValidateSignature
- hap: ValidateSignature
- hap: PairVerify with unknown client_id:
- wrong pin code
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/0aa140dc7b2d4219.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/hap/client_pairing.go:173
Proof string `tlv8:"4"` // server proof
State byte `tlv8:"6"`
Error byte `tlv8:"7"`
EncryptedData string `tlv8:"5"` // skip EncryptedData validation (for MFi devices)
}
if err = tlv8.UnmarshalReader(res.Body, res.ContentLength, &plainM4); err != nil {
return
}
if plainM4.State != StateM4 {
return newResponseError(plainM3, plainM4)
}
if plainM4.Error != 0 {
return newPairingError(plainM4.Error)
}
// STEP M4. Verify response
if !session.VerifyServerAuthenticator([]byte(plainM4.Proof)) {
return errors.New("hap: VerifyServerAuthenticator")
}
// STEP M5. Generate signature
localSign, err := hkdf.Sha512(
sessionShared, "Pair-Setup-Controller-Sign-Salt", "Pair-Setup-Controller-Sign-Info",
)
if err != nil {
return
}
b := Append(localSign, c.ClientID, c.ClientPublic())
signature, err := ed25519.Signature(c.ClientPrivate, b)
if err != nil {
return
}
// STEP M5. Generate payload
plainM5 := struct {View on GitHub (pinned to c245815e75)