---
title: 'Troubleshooting Proxy Issues'
icon: 'wrench'
---

### The Global Limiter Problem

If you are behind a proxy/load balancer (usually the case with most hosting
services, e.g. Heroku, Bluemix, AWS ELB, Nginx, Cloudflare, Akamai, Fastly,
Firebase Hosting, Rackspace LB, Riverbed Stingray, etc.), the IP address of the
request might be the IP of the load balancer/reverse proxy (making the rate
limiter effectively a global one and blocking all requests once the limit is
reached) or `undefined`.

To solve this issue, assuming the proxy (or proxies) set the `X-Forwarded-For`
header, please follow the steps given below.

<Steps>

    <Step title="Using the 'trust proxy' setting">
    	Add the following line to your code, right after you create the express
    	application:

    	```ts
    	app.set('trust proxy', 1 /* number of proxies between user and server */)
    	```
    </Step>
    <Step title="Finding the magic number">
    	To find the correct number of proxies between the user and the server,
    	create a test endpoint that returns the client IP:

    	```ts
    	app.get('/ip', (request, response) => {
    		response.send(request.ip);
    	});
    	```

    	Make a `get` request to `/ip` and check the IP address returned in the
    	response. If it matches your IP address (which you can get by visiting
    	[ip.nfriedly.com](http://ip.nfriedly.com/) or
    	[api.ipify.org](https://api.ipify.org/), then the number of proxies is
    	correct and the rate limiter should now work correctly. If not, then keep
    	increasing the number until it does.
    </Step>

</Steps>

For more information about the `trust proxy` setting, take a look at the
[official Express documentation](https://expressjs.com/en/guide/behind-proxies.html).

#### Forwarded header

If the server instead sets the `Forwarded` header, the steps are similar except
that you'll need a
[custom keyGenerator](/reference/error-codes#err-erl-forwarded-header) because
express does not have built-in support for the `Forwarded` header (as of version
5.1.0),

### Port Numbers in IP Addresses

Sometimes, a problem arises because the format of the `X-Forwarded-For` header
isn't standardized between every reverse proxy out there, and Express takes the
trusted value verbatim and sets it as `request.ip`.

While some reverse proxy pass a comma delimited list of IP address, some proxies
(for example, Azure's Application Gateway) will pass a comma delimited list of
`IP:PORT` instead, where the port is the source port, that can change on every
request. Because of this, a user can simply close and re-open their browser to
bypass the rate limit timer as the source port of their HTTP request will
change, even if their IP is the same. This could also be automated in some kind
of script for API abuse.

As a workaround, you could strip the port number from the IP address by using a
custom `keyGenerator` function:

```ts
keyGenerator(request: Request, _response: Response): string {
	if (!request.ip) {
		console.error('Warning: request.ip is missing!')
		return request.socket.remoteAddress
	}

	return request.ip.replace(/:\d+[^:]*$/, '')
}
```

See issue [#234](https://github.com/nfriedly/express-rate-limit/issues/234) for
more info.
