AlexxIT/go2rtc · error
refresh token is required
Error message
refresh token is required
What it means
The Ring client factory requires a non-empty RefreshToken when auth is provided as RefreshTokenAuth. An empty token cannot form a cache key nor authenticate, so the call fails immediately with this error.
Solutions
- Obtain a valid refresh token (via ring auth flow /, per ring-client-api docs) and pass it in RefreshTokenAuth.
- Check the env var/config key holding the token is set and non-empty before constructing the client.
- Fail fast at startup: validate the token string before calling the library.
- Log the length (never the value) of the token to confirm it is loaded.
Example fix
// before
client, _ := ring.NewClient(ring.RefreshTokenAuth{RefreshToken: os.Getenv("RING_TOKEN")})
// after
rt := os.Getenv("RING_TOKEN")
if rt == "" {
return fmt.Errorf("RING_TOKEN must be set")
}
client, err := ring.NewClient(ring.RefreshTokenAuth{RefreshToken: rt}) Defensive patterns
Strategy: validation
Validate before calling
if auth.RefreshToken == "" { return errors.New("ring refresh token must be configured before NewClient") } Try / catch
client, err := ring.NewClient(ring.RefreshTokenAuth{RefreshToken: rt})
if err != nil {
if err.Error() == "refresh token is required" {
return fmt.Errorf("config: RING_REFRESH_TOKEN not set: %w", err)
}
return err
} Prevention
- Validate all auth config at process startup, fail fast
- Keep tokens in env vars or a secrets manager, never hardcode
- Log token presence (length) rather than value when debugging config
- Persist refreshed tokens so they are available on restart
When it happens
Trigger: Passing ring.RefreshTokenAuth{RefreshToken: ""} (zero-value struct) or a variable that was never populated to the Ring client constructor.
Common situations: Config file/env var for the refresh token missing or empty; after a refactor the token field was renamed and no longer filled; tokens loaded from secrets manager returned empty string on failure that was ignored.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- email and password are required
- invalid auth type
- failed to parse refresh token
- config file disabled
- exec: rtsp module disabled
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/f2c90e11d7390fdd.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/ring/api.go:163
clientAPIBaseURL = "https://api.ring.com/clients_api/"
deviceAPIBaseURL = "https://api.ring.com/devices/v1/"
commandsAPIBaseURL = "https://api.ring.com/commands/v1/"
appAPIBaseURL = "https://prd-api-us.prd.rings.solutions/api/v1/"
oauthURL = "https://oauth.ring.com/oauth/token"
apiVersion = 11
defaultTimeout = 20 * time.Second
maxRetries = 3
sessionValidTime = 12 * time.Hour
)
func NewRestClient(auth interface{}, onTokenRefresh func(string)) (*RingApi, error) {
var cacheKey string
// Create cache key based on auth data
switch a := auth.(type) {
case RefreshTokenAuth:
if a.RefreshToken == "" {
return nil, fmt.Errorf("refresh token is required")
}
cacheKey = "refresh:" + a.RefreshToken
case EmailAuth:
if a.Email == "" || a.Password == "" {
return nil, fmt.Errorf("email and password are required")
}
cacheKey = "email:" + a.Email + ":" + a.Password
default:
return nil, fmt.Errorf("invalid auth type")
}
cacheMutex.Lock()
defer cacheMutex.Unlock()
if cachedClient, ok := clientCache[cacheKey]; ok {
// Check if token is not nil and not expired
if cachedClient.authToken != nil && time.Now().Before(cachedClient.tokenExpiry) {
cachedClient.onTokenRefresh = onTokenRefreshView on GitHub (pinned to c245815e75)