In my HAProxy load balancer, I have the following config chunks:

    mode                    http
    log                     global
    option                  httplog clf
    option                  dontlognull
    option http-server-close
    option forwardfor       except
    option                  redispatch

frontend  main_http *:80
    option forwardfor except
    option httpclose
    default_backend         backend_http

backend backend_http
    balance     roundrobin
    option httpchk
    server  node1 check port 80
    server  node2 check port 80
    server  node3 check port 80

On the nodes (Tomcat), I'm logging requests in this format (combined with x-forwarded-for in the first field and the real REMOTE_ADDR tacked onto the end):

pattern='%{X-Forwarded-For}i - %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %a'

This seems to work well for most requests, but in some cases, I assume in which the clients are behind proxies themselves, I'm seeing requests where the first field contains these values (each line represents one real request, I mangled the real IPs for privacy):,,, 
unknown, unknown,,, 216.x.y.194,, 38.x.y.5, 

According to the HAproxy docs, the last X-Forwarded-For should be the correct one that it appended, but this doesn't appear to be the case. My application uses the client IP for a geo lookup, so this isn't just a logging issue, it's actually screwing things up.

What I'd like to do is: instead of having HAproxy append the client's IP to the existing X-Forwarded-For header it receives, simply overwrite it. So if it receives X-Forwarded-For: from IP addres, what it would send to the clients is just X-Forwarded-For: Is there any way to do this? I'd like to know why such obvious junk is making it to the nodes - unknown, unknown is clearly junk info - but I'll settle for a workaround if one exists.

Thanks in advance.

3 Answers 3


Tear it off the request header, before HAProxy adds its own:

reqidel ^X-Forwarded-For:.*

The risk to this change is that you'll lose your information about the "real" client IP address - your logs will then be showing the IP of the proxy server that the client is using. Sounds like you're ok with that!

As an aside, see this question for some interesting info on confusion over the append order of the X-Forwarded-For header.

  • Brilliant. I don't know why I didn't think of simply deleting the existing header. I'll give that a try - thanks!
    – Evan
    Feb 10, 2012 at 22:13
  • Worked beautifully. I'd upvote your answer but guess I can't as a newbie.
    – Evan
    Feb 11, 2012 at 21:58
  • @Evan There's an outlined checkmark under the up/down vote arrows that marks the answer as accepted - it awards some rep as well as marking it as having resolved the issue for anyone who finds this question in the future while searching. Feb 11, 2012 at 22:22

For anyone who is still puzzled, you can use one of these two snippets directly:


backend forward_real_ip
    mode http
    reqidel ^X-Forwarded-For:.*
    option forwardfor


backend forward_real_ip
   mode http
   http-request set-header X-Forwarded-For %[src]

See the HAProxy docs:


If you look at haproxy documentation specifically at forwardedfor option, you can read:

option forwardfor [ except <network> ] [ header <name> ] [ if-none ]

You can change the corresponding line in your config something else like:

option forwardfor except header My-X-Forwarded-For

This way you will end up by having two X-Forwarded-For headers. It may be useful for you to keep the clients real IPs and at the same time, you get haproxy inserting its header without confusion.

This is just another option you may be interested in :)

  • Yeah, I had considered that but it would require code changes in the app to have it read a different header, and I'd like not to do that if possible. Thanks though.
    – Evan
    Feb 11, 2012 at 21:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .