gofr-dev/gofr · error
requestsPerSecond must be positive
Error message
requestsPerSecond must be positive
What it means
errInvalidRequestsPerSecond is returned by RateLimiterConfig.Validate when RequestsPerSecond is zero or negative. The token-bucket rate limiter cannot function without a positive refill rate, so configuration is rejected up front.
Source
Thrown at pkg/gofr/http/middleware/rate_limiter.go:17
package middleware
import (
"context"
"errors"
"fmt"
"math"
"net"
"net/http"
"strings"
gofrHttp "gofr.dev/pkg/gofr/http"
)
var (
// errInvalidRequestsPerSecond is returned when RequestsPerSecond is not positive.
errInvalidRequestsPerSecond = errors.New("requestsPerSecond must be positive")
// errInvalidBurst is returned when Burst is not positive.
errInvalidBurst = errors.New("burst must be positive")
)
// RateLimiterConfig holds configuration for rate limiting.
//
// Note: The default implementation uses in-memory token buckets and is suitable
// for single-pod deployments. In multi-pod deployments, each pod will enforce
// limits independently. For distributed rate limiting across multiple pods,
// a Redis-backed store can be implemented in a future update.
//
// Security: When using PerIP=true, only enable TrustedProxies if your application
// is behind a trusted reverse proxy (nginx, ALB, etc.) that sets X-Forwarded-For.
// Without trusted proxies, clients can spoof IP addresses to bypass rate limits.
//
// Cleanup: The rate limiter starts a background goroutine that runs for the
// application lifetime. This is acceptable for long-running servers but considerView on GitHub (pinned to 187eb24962)
Solutions
- Set RequestsPerSecond to a positive float (e.g. 10) in the RateLimiterConfig
- If loading from config/env, validate the parsed value is > 0 before building the middleware
- Provide a sensible default (e.g. 100) when the config value is missing
Example fix
// before
cfg := middleware.RateLimiterConfig{}
// after
cfg := middleware.RateLimiterConfig{RequestsPerSecond: 100, Burst: 200} Defensive patterns
Strategy: validation
Validate before calling
if cfg.RequestsPerSecond <= 0 { return fmt.Errorf("RequestsPerSecond must be > 0, got %v", cfg.RequestsPerSecond) } Type guard
func validRateConfig(c RateLimiterConfig) bool { return c.RequestsPerSecond > 0 && c.Burst > 0 } Prevention
- Never rely on Go zero values for rate limit configs; set explicit defaults
- Validate parsed env/config values before constructing middleware
- Document required fields in your config struct
When it happens
Trigger: Constructing a RateLimiterConfig with RequestsPerSecond: 0, a negative value, or leaving it as the zero value in a struct literal that doesn't set it.
Common situations: Forgetting to set RequestsPerSecond because Go zero-values it; computing the rate from a config/env value that parses to 0; unit changes (per-minute vs per-second) yielding sub-1 values.
Related errors
- burst must be positive
- invalid rate limiter config: %v
- %w: deleting document: %w
- invalid Azure configuration: share name is required
- invalid Azure configuration: account name is required
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/bc71beb012a2e49f.
Report an issue: GitHub.