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

  1. Obtain a valid refresh token (via ring auth flow /, per ring-client-api docs) and pass it in RefreshTokenAuth.
  2. Check the env var/config key holding the token is set and non-empty before constructing the client.
  3. Fail fast at startup: validate the token string before calling the library.
  4. 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

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


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 = onTokenRefresh

View on GitHub (pinned to c245815e75)