{"record":{"id":"cd8bc28c6a41f996","repo":"AlexxIT/go2rtc","slug":"session-validation-failed-w","errorCode":null,"errorMessage":"session validation failed: %w","messagePattern":"session validation failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/ring/api.go","lineNumber":406,"sourceCode":"\nfunc (c *RingApi) GetSocketTicket() (*SocketTicketResponse, error) {\n\tresponse, err := c.Request(\"POST\", AppAPI(\"clap/ticket/request/signalsocket\"), nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to fetch socket ticket: %w\", err)\n\t}\n\n\tvar ticket SocketTicketResponse\n\tif err := json.Unmarshal(response, &ticket); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal socket ticket response: %w\", err)\n\t}\n\n\treturn &ticket, nil\n}\n\nfunc (c *RingApi) Request(method, url string, body interface{}) ([]byte, error) {\n\t// Ensure we have a valid session\n\tif err := c.ensureSession(); err != nil {\n\t\treturn nil, fmt.Errorf(\"session validation failed: %w\", err)\n\t}\n\n\tvar bodyReader io.Reader\n\tif body != nil {\n\t\tjsonBody, err := json.Marshal(body)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to marshal request body: %w\", err)\n\t\t}\n\t\tbodyReader = bytes.NewReader(jsonBody)\n\t}\n\n\t// Create request\n\treq, err := http.NewRequest(method, url, bodyReader)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\n\t// Set headers","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/ring/api.go#L388-L424","documentation":"RingApi.Request wraps any error from ensureSession() with 'session validation failed'. The library maintains a Ring session (auth token) and validates/refreshes it before every API call; if that validation or refresh fails, the request is aborted before being sent. This means the Ring credentials or session state are unusable.","triggerScenarios":"Calling RingApi.Request (any method/URL) when ensureSession() fails: no session exists and initial login fails, the stored session/token is expired and refresh fails, or invalid credentials were supplied to the client.","commonSituations":"Wrong or revoked Ring username/password or refresh token; Ring changed its auth API; network outage or firewall blocking Ring auth endpoints; 2FA/verification code required but not provided; system clock skew invalidating tokens.","solutions":["Verify Ring credentials (email/password or refresh token) supplied to the client are correct and current","Re-authenticate from scratch: clear cached session/token state and log in again to obtain a fresh session","Check network connectivity to Ring's auth/API endpoints (proxy, firewall, DNS)","If 2FA is enabled on the account, supply the required verification code/token as the library expects","Check that the system clock is accurate (large skew breaks token validity)"],"exampleFix":"// before\nticket, err := c.ensureSession()\nif err != nil {\n    return nil, fmt.Errorf(\"session validation failed: %w\", err) // opaque to caller\n}\n// after\nticket, err := c.ensureSession()\nif err != nil {\n    if errors.Is(err, ErrInvalidCredentials) {\n        return nil, fmt.Errorf(\"ring login rejected credentials, re-authenticate: %w\", err)\n    }\n    return nil, fmt.Errorf(\"session validation failed: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"// Go: check session state before calling\nif err := api.Ping(ctx); err != nil {\n    // force re-login before real calls\n    if reauthErr := api.Reauthenticate(); reauthErr != nil {\n        return fmt.Errorf(\"cannot establish ring session: %w\", reauthErr)\n    }\n}","typeGuard":null,"tryCatchPattern":"// Go\nresp, err := api.Request(\"GET\", url, nil)\nif err != nil {\n    if strings.Contains(err.Error(), \"session validation failed\") {\n        // re-authenticate then retry once\n        if rErr := api.Reauthenticate(); rErr == nil {\n            resp, err = api.Request(\"GET\", url, nil)\n        }\n    }\n    if err != nil {\n        return err\n    }\n}","preventionTips":["Refresh credentials/session proactively before expiry instead of relying on lazy validation","Use a refresh token rather than password-based login where the library supports it","Monitor NTP/clock sync on hosts using the client","Handle 2FA requirements at initial login, not mid-request"],"tags":["authentication","session","ring-api"],"backgroundTag":"authentication-required","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}