{"record":{"id":"41fef40fece87e8d","repo":"gofr-dev/gofr","slug":"invalid-rate-limiter-config-v","errorCode":null,"errorMessage":"invalid rate limiter config: %v","messagePattern":"invalid rate limiter config: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/gofr/http/middleware/rate_limiter.go","lineNumber":116,"sourceCode":"\trealIP := r.Header.Get(\"X-Real-IP\")\n\treturn strings.TrimSpace(realIP)\n}\n\n// getRemoteAddr extracts IP from RemoteAddr.\nfunc getRemoteAddr(r *http.Request) string {\n\tip, _, err := net.SplitHostPort(r.RemoteAddr)\n\tif err != nil {\n\t\treturn r.RemoteAddr\n\t}\n\n\treturn ip\n}\n\n// RateLimiter creates a middleware that limits requests based on the configuration.\nfunc RateLimiter(config RateLimiterConfig, m metrics) func(http.Handler) http.Handler {\n\t// Validate configuration\n\tif err := config.Validate(); err != nil {\n\t\tpanic(fmt.Sprintf(\"invalid rate limiter config: %v\", err))\n\t}\n\n\t// Use in-memory store if none provided\n\tif config.Store == nil {\n\t\tconfig.Store = NewMemoryRateLimiterStore(config)\n\t}\n\n\t// Start cleanup routine with context.Background().\n\t// The cleanup goroutine runs for the application lifetime.\n\t// For graceful shutdown, call config.Store.StopCleanup() in your shutdown handler.\n\tctx := context.Background()\n\tconfig.Store.StartCleanup(ctx)\n\n\treturn func(next http.Handler) http.Handler {\n\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\t// Skip rate limiting for health check endpoints\n\t\t\tif isWellKnown(r.URL.Path) {\n\t\t\t\tnext.ServeHTTP(w, r)","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/http/middleware/rate_limiter.go#L98-L134","documentation":"This is a panic message raised inside the RateLimiter middleware constructor when config.Validate() returns an error (non-positive RequestsPerSecond or Burst). Invalid rate limiting configuration is treated as a programming/deployment error, so it fails fast at startup rather than at request time.","triggerScenarios":"Calling middleware.RateLimiter(RateLimiterConfig{...}) with RequestsPerSecond <= 0 or Burst <= 0; typically during server bootstrap.","commonSituations":"Deployment misconfiguration where rate limit env vars are empty and parse to 0; refactoring that drops a field from the config literal; test setups that forget to populate the config.","solutions":["Fix the RateLimiterConfig values so RequestsPerSecond > 0 and Burst > 0 before calling RateLimiter()","Call config.Validate() yourself earlier and log/exit with a friendly message instead of reaching the panic","Sanitize env/config parsing: treat missing or zero rate values as defaults at load time"],"exampleFix":"// before\nmiddleware.RateLimiter(middleware.RateLimiterConfig{RequestsPerSecond: rps}) // rps=0 from env\n// after\nif rps <= 0 { rps = 100 }\nif burst <= 0 { burst = 200 }\nmiddleware.RateLimiter(middleware.RateLimiterConfig{RequestsPerSecond: rps, Burst: burst})","handlingStrategy":"validation","validationCode":"if err := cfg.Validate(); err != nil { logger.Fatalf(\"rate limiter misconfigured: %v\", err) }","typeGuard":"func validRateConfig(c RateLimiterConfig) bool { return c.RequestsPerSecond > 0 && c.Burst > 0 }","tryCatchPattern":"defer func() { if r := recover(); r != nil { logger.Fatalf(\"rate limiter init panicked: %v\", r) } }() // around middleware wiring","preventionTips":["Call Validate() on all middleware configs at startup before the panic path","Add startup smoke tests that construct every middleware with production config","Centralize env parsing so zero-value rates become safe defaults"],"tags":["rate-limiting","panic","configuration","middleware"],"backgroundTag":"panic-on-invalid-config","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}