AlexxIT/go2rtc · error
nest: max retries exceeded
Error message
nest: max retries exceeded
What it means
ExchangeSDP retries the SDP exchange a limited number of times (e.g. to wait until the camera becomes available); if every attempt fails without producing an answer SDP, it gives up and returns this sentinel error. It is an exhaustion signal rather than a specific HTTP failure — each attempt had its own failure reason.
Solutions
- Fix the underlying per-attempt failure (check for an earlier 'nest: wrong status' error or logs) — refresh tokens, free the camera, restore connectivity.
- Stop competing stream clients so the camera becomes available within the retry window.
- Increase the retry count/delay if the camera is slow to become ready.
- Verify camera power/network status; a camera that never answers will always exhaust retries.
Example fix
// before // 3 quick retries, camera still busy answer, err := api.ExchangeSDP(ctx, offer) // after // stop other viewers first, then retry with longer window stopOtherViewers(cameraID) answer, err := api.ExchangeSDP(ctx, offer)
Defensive patterns
Strategy: fallback
Validate before calling
// check camera reachability before attempting SDP exchange
if !cameraOnline(cameraID) {
return errors.New("camera offline; skipping SDP exchange")
} Try / catch
answer, err := api.ExchangeSDP(ctx, offer)
if err != nil && strings.Contains(err.Error(), "max retries exceeded") {
// stop competing viewers, wait, then fall back to snapshot stream
stopOtherViewers(cameraID)
return fallbackToSnapshotStream(ctx, cameraID)
} Prevention
- Ensure exclusive access to the camera stream before connecting.
- Alert on repeated retry exhaustion — it usually signals camera offline or busy.
- Increase retry window for slow cameras if acceptable for UX.
- Check camera power/network health as part of the runbook.
When it happens
Trigger: Calling ExchangeSDP when all retry attempts fail (camera busy/offline, token invalid, or transient Nest cloud errors persist across the whole retry window).
Common situations: Camera perpetually busy because another client holds the stream; camera offline/unreachable; credentials never refreshed so every attempt 401s; retry budget too small for slow cameras.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/d932b373a9f3df65.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/nest/api.go:227
Answer string `json:"answerSdp"`
ExpiresAt time.Time `json:"expiresAt"`
MediaSessionID string `json:"mediaSessionId"`
} `json:"results"`
}
if err = json.NewDecoder(res.Body).Decode(&resv); err != nil {
return "", err
}
a.StreamProjectID = projectID
a.StreamDeviceID = deviceID
a.StreamSessionID = resv.Results.MediaSessionID
a.StreamExpiresAt = resv.Results.ExpiresAt
return resv.Results.Answer, nil
}
return "", errors.New("nest: max retries exceeded")
}
func (a *API) refreshToken() error {
// Get the cached API with matching token to get credentials
var refreshKey string
cacheMu.Lock()
for key, api := range cache {
if api.Token == a.Token {
refreshKey = key
break
}
}
cacheMu.Unlock()
if refreshKey == "" {
return errors.New("nest: unable to find cached credentials")
}
View on GitHub (pinned to c245815e75)