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
- Set Requests to a positive number, e.g. RateLimiterConfig{Requests: 100, Window: time.Minute}.
- Check the error returned by Validate instead of ignoring it, since Validate also mutates Requests to the 60 default.
- 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
- Always set Requests explicitly — the zero value of float64 means 0 requests.
- Check Validate's error return; Validate silently rewrites invalid values to defaults.
- Validate config-file values at parse time, before constructing the limiter.
- Cover limiter config with a table test asserting Requests > 0.
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
- burst must be greater than requests per window
- validate func is empty
- unsupported config file format
- invalid RBAC config: %w
- endpoint[%d]: %w: %s
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/a4d88728971210ec.
Report an issue: GitHub.