gofr-dev/gofr · error

requests must be greater than 0 per configured time window

Error message

requests must be greater than 0 per configured time window

What it means

errInvalidRequestRate (rate_limiter_config.go:11) is returned by RateLimiterConfig.Validate when Requests <= 0 — a rate limiter that allows zero requests per window is meaningless. Validate reports the error but still repairs the config by defaulting Requests to 60, so callers that ignore the return value get a silently defaulting limiter.

Source

Thrown at pkg/gofr/service/rate_limiter_config.go:11

package service

import (
	"errors"
	"fmt"
	"net/http"
	"time"
)

var (
	errInvalidRequestRate     = errors.New("requests must be greater than 0 per configured time window")
	errBurstLessThanRequests  = errors.New("burst must be greater than requests per window")
	errInvalidRedisResultType = errors.New("unexpected Redis result type")
)

const (
	unknownServiceKey = "unknown"
	methodHTTP        = "http"
	methodHTTPS       = "https"
)

// RateLimiterConfig with custom keying support.
type RateLimiterConfig struct {
	Requests float64                    // Number of requests allowed
	Window   time.Duration              // Time window (e.g., time.Minute, time.Hour)
	Burst    int                        // Maximum burst capacity (must be > 0)
	KeyFunc  func(*http.Request) string // Optional custom key extraction
	Store    RateLimiterStore
}

View on GitHub (pinned to 187eb24962)

Solutions

  1. Set Requests to a positive number, e.g. RateLimiterConfig{Requests: 100, Window: time.Minute}.
  2. Check the error returned by Validate instead of ignoring it, since Validate also mutates Requests to the 60 default.
  3. Validate config-loaded values before wiring them into RateLimiterConfig (reject 0/negative at parse time).

Example fix

// before
cfg := &service.RateLimiterConfig{Window: time.Minute} // Requests == 0
// after
cfg := &service.RateLimiterConfig{Requests: 60, Window: time.Minute, Burst: 10}
Defensive patterns

Strategy: validation

Validate before calling

if cfg.Requests <= 0 {
	return fmt.Errorf("Requests must be > 0, got %f", cfg.Requests)
}
if err := cfg.Validate(); err != nil { return err }

Type guard

func validRate(cfg *service.RateLimiterConfig) bool {
	return cfg != nil && cfg.Requests > 0
}

Try / catch

if err := cfg.Validate(); err != nil {
	if errors.Is(err, errInvalidRequestRate) {
		log.Printf("rate limit config invalid, Validate applied default (60/min): %v", err)
	}
}

Prevention

When it happens

Trigger: Constructing RateLimiterConfig{Requests: 0} (or negative, or left as the zero-value float64) and calling Validate; also when Burst defaults/promotions make the subsequent burst check fire.

Common situations: Forgetting to set Requests because it is a float64 and the zero value looks like 'unset'; loading rate-limit numbers from config/env where an empty string parses to 0; copy-pasting a config struct without fields.

Related errors


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/a4d88728971210ec. Report an issue: GitHub.