Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I've setup nginx as a reverse proxy for a couple of apache backend/upstream servers.

Using the GeoLite database from MaxMind, I'm trying to loadbalance requests between the two servers dependent on the clients country code.

Nginx Configuration:

geo $geo {
        default default;
        include geo.conf;
    upstream default.backend {
        server; #Server A
        server; #Server B
    upstream DE.backend {
        server; #Server A
    upstream US.backend {
        server; #Server B
server {
        listen 80;
        location / {
            proxy_pass http://$geo.backend;
            proxy_set_header        Host            $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

So I'm trying to send any German clients to server A, and US clients to server B, and any other clients not matching German or US country codes to be loadbalanced between servers A & B.

However, since geo.conf contains country codes for many (all) other countries, these values are being set to the variable $geo, as opposed to the 'default' value.

With my current configuration this causes '502 Bad Gateway' errors with all requests that aren't DE or US.

Nginx error log:

2013/10/11 08:18:50 [error] 25017#0: *1 no resolver defined to resolve NL.backend, client:, server:, request: "GET / HTTP/1.1", host: ""

Nginx access log: - - [11/Oct/2013:08:18:50 -0700] "GET / HTTP/1.1" 502 574 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31" "-"

How can I configure nginx.conf to interpret any IP country code value from geo.conf that's not DE or US as default, and loadbalance it accordingly to upstream default.backend?

share|improve this question

default specified inside geo specifies only a default value for IP addresses which aren't in the database at all. So $geo will always have country codes for whatever is present in the database. So default here does nothing for you.

To deal with this, use a map in addition.

map $geo $backend {
    default default;
    US US;
    DE DE;
share|improve this answer
Thanks for this. So do i add this to my existing config? – Elijah Paul Oct 11 '13 at 16:27
Managed to figure it out. I got confused by the $backend variable. Didn't know that I had to change proxy_pass http://$geo.backend; to proxy_pass http://$backend.backend; – Elijah Paul Oct 11 '13 at 16:40
@ElijahPaul can you post the updated version with your changes? It would help alot. – Donny V Jan 8 '15 at 5:19

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.