{"record":{"id":"663993ee9adaf706","repo":"gofiber/fiber","slug":"servers-cannot-be-empty","errorCode":null,"errorMessage":"Servers cannot be empty","messagePattern":"Servers cannot be empty","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/proxy/config.go","lineNumber":131,"sourceCode":"\tif len(config) < 1 {\n\t\treturn ConfigDefault\n\t}\n\n\t// Override default config\n\tcfg := config[0]\n\n\t// Set default values\n\tif cfg.Timeout <= 0 {\n\t\tcfg.Timeout = ConfigDefault.Timeout\n\t}\n\n\tif cfg.MaxConnsPerHost <= 0 {\n\t\tcfg.MaxConnsPerHost = ConfigDefault.MaxConnsPerHost\n\t}\n\n\t// Set default values\n\tif len(cfg.Servers) == 0 && cfg.Client == nil {\n\t\tpanic(\"Servers cannot be empty\")\n\t}\n\treturn cfg\n}\n","sourceCodeStart":113,"sourceCodeEnd":135,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/proxy/config.go#L113-L135","documentation":"proxy.Balancer requires at least one upstream. configDefault panics when Config.Servers is empty AND Config.Client is nil — a balancer with no backends cannot forward any request, so this is treated as a hard configuration error rather than a runtime failure on the first request. Note that supplying Config.Client bypasses the Servers requirement (and the Server-validating loop in proxy.go).","triggerScenarios":"proxy.Balancer() with no args, or proxy.Balancer(proxy.Config{}) where neither Servers nor Client is set. Also reached when Servers is built from an env var that is empty and the code still calls Balancer.","commonSituations":"Backend list loaded from config that is empty in a local/dev environment; refactor that moves Servers into a Client but leaves the old Balancer(config) call with an empty Servers; conditional wiring that drops the config argument.","solutions":["Provide a non-empty Servers list: proxy.Balancer(proxy.Config{Servers: []string{\"http://localhost:8081\", \"http://localhost:8082\"}}).","Provide a pre-built Client (*fasthttp.LBClient) if you need full control over the upstream set.","Guard the app.Use(proxy.Balancer(...)) call so the middleware is only registered when upstreams are configured."],"exampleFix":"// before\napp.Use(proxy.Balancer(proxy.Config{}))\n\n// after\napp.Use(proxy.Balancer(proxy.Config{\n    Servers: []string{\"http://localhost:8081\"},\n}))","handlingStrategy":"validation","validationCode":"func buildProxyConfig(servers []string, client *fasthttp.LBClient) (proxy.Config, error) {\n    if len(servers) == 0 && client == nil {\n        return proxy.Config{}, errors.New(\"proxy: Servers cannot be empty (or set Client)\")\n    }\n    return proxy.Config{Servers: servers, Client: client}, nil\n}","typeGuard":"func hasProxyTarget(servers []string, client *fasthttp.LBClient) bool {\n    return len(servers) > 0 || client != nil\n}","tryCatchPattern":null,"preventionTips":["Register proxy.Balancer only when at least one upstream is configured.","Fail fast at startup if the upstreams env var is empty in production.","Decide explicitly between Servers (declarative) and Client (pre-built) — do not leave both unset."],"tags":["proxy","balancer","config","required-field","startup-panic"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}