{"record":{"id":"69462624703a5c34","repo":"dutchcoders/transfer.sh","slug":"forbidden","errorCode":null,"errorMessage":"Forbidden","messagePattern":"Forbidden","errorType":"http","errorClass":null,"httpStatus":403,"severity":"error","filePath":"server/ip_filter.go","lineNumber":204,"sourceCode":"\treturn &ipFilterMiddleware{ipFilter: f, next: next}\n}\n\n// WrapIPFilter is equivalent to newIPFilter(opts) then Wrap(next)\nfunc WrapIPFilter(next http.Handler, opts *IPFilterOptions) http.Handler {\n\treturn newIPFilter(opts).Wrap(next)\n}\n\ntype ipFilterMiddleware struct {\n\t*ipFilter\n\tnext http.Handler\n}\n\nfunc (m *ipFilterMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tremoteIP := realip.FromRequest(r)\n\n\tif !m.ipFilter.Allowed(remoteIP) {\n\t\t//show simple forbidden text\n\t\thttp.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)\n\t\treturn\n\t}\n\n\t//success!\n\tm.next.ServeHTTP(w, r)\n}\n","sourceCodeStart":186,"sourceCodeEnd":211,"githubUrl":"https://github.com/dutchcoders/transfer.sh/blob/c37bfd95797fd6da8a6da53fc13d191994b3f687/server/ip_filter.go#L186-L211","documentation":"This is an HTTP 403 Forbidden response generated by the IP filter middleware: the client's remote IP (resolved via realip.FromRequest, typically checking X-Forwarded-For/X-Real-IP headers before RemoteAddr) was not accepted by the configured IPFilterOptions allow/deny rules, so the request is rejected before ever reaching the wrapped handler. It fires whenever a request originates from an IP that is not explicitly allowed (or is denied) by the filter configuration — a generic validation guard, with the faulting input being the client's remote address. The server returns the plain status text 'Forbidden' and stops processing; clients must connect from a whitelisted IP for requests to pass to the next handler.","triggerScenarios":"Any request to the linx server when the client's resolved remote IP is not in the ip-filter allowlist (or is in the deny list), typically configured via the ip-filter-action/ip filter options.","commonSituations":"Server moved behind a reverse proxy so realip resolves to the proxy address instead of the client; allowlist contains stale IPs after client IP change; IPv6 client not covered by an IPv4-only allowlist; misformatted CIDR in config.","solutions":["Verify the client IP with `curl ifconfig.me` and add it (or its CIDR) to the IP filter config","Behind a proxy, enable real IP extraction (X-Forwarded-For / X-Real-IP trusted proxy settings) so the filter sees the true client IP","Use correct CIDR notation covering IPv6 if applicable","Check config parsing — an invalid filter entry can behave as allow-none","Temporarily test with the filter disabled to confirm it is the cause"],"exampleFix":"// before\n--ip-filter-allowed-ips 10.0.0.0/8   # client is on IPv6\n// after\n--ip-filter-allowed-ips 10.0.0.0/8,2001:db8::/32","handlingStrategy":"validation","validationCode":"# check whether your current IP passes the filter before calling the API\nMY_IP=$(curl -s ifconfig.me)\ngrep -qE \"(^|,)${MY_IP}(,|$)\" ipfilter.conf || echo \"IP $MY_IP not in allowlist\"","typeGuard":"null","tryCatchPattern":"try {\n  const res = await fetch(url);\n  if (res.status === 403) {\n    // client IP blocked: request allowlist change via admin channel\n    throw new Error('Forbidden: IP not allowlisted');\n  }\n} catch (err) { /* escalate to network admin */ }","preventionTips":["Keep the allowlist updated with egress IPs/NAT addresses of all clients","Behind a proxy, configure trusted X-Forwarded-For handling so real IPs are seen","Include IPv6 ranges in the filter","Use CIDR notation to cover dynamic IP ranges"],"tags":["http-403","ip-filter","access-control"],"backgroundTag":"ip-filter-forbidden","analyzedSha":"c37bfd95797fd6da8a6da53fc13d191994b3f687","analyzedAt":"2026-09-05T10:21:07.548Z","contentChangedAt":"2026-09-05T10:21:07.548Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}