I am using a simple nginx instance to proxy REST calls to another server. The purpose of my proxy is to allow the use of cookies for authentication. I have it working, except for one problem. The server providing the REST service is sending the header Access-Control-Allow-Origin *. That header is too permissive for cookie based authentication. I need to replace that header with one that is more restrictive.

Here is a subset of my nginx config:

map $http_origin $cors_header {
    default "";
    "~^https?://[^/]+\.mydomain\.com(:[0-9]+)?$" $http_origin;

server {    
    location / {
        proxy_pass https://myrestserver.com/api;
        add_header Access-Control-Allow-Origin $cors_header;
        add_header Access-Control-Allow-Credentials true;

My problem is that I end up with two Access-Control-Allow-Origin headers present in my response. How can I replace the header that comes back from the REST server so that only my version of the header is present in the final response?

3 Answers 3


The best thing to do would be to change the response on the REST server side, but, assuming you don't have control of the REST server, there is a module for Nginx that can modify headers called ngx_headers_more: https://github.com/openresty/headers-more-nginx-module

You'll have to install the module (this will likely involve building nginx from source and adding the module in ./configure, as described in the github readme). For your specific problem, once you install it you can add this directive in any block

more_set_headers "Access-Control-Allow-Origin: $cors_header"
  • You may or may not need to use "more_clear_headers" before "more_set_headers". I do, but not sure if it was me being cautious or actually needing to. Building nginx is pretty easy, I have a guide coming out that includes that soon.
    – Tim
    Jan 25, 2016 at 22:00
  • 2
    You don't actually! As the docs say, more_set_headers "Replaces (if any) or adds (if not any) the specified output headers..." but I doubt the cautious approach adds significant overhead. Jan 25, 2016 at 22:05
  • Good to know :) You're right, I clear some headers like "Server" (for security) and "Pragma" (because it's old) and just set the headers I care about.
    – Tim
    Jan 25, 2016 at 22:08
  • This did work without needing to use more_clear_headers. Thanks! Jan 26, 2016 at 4:48

this works without extra nginx modules

proxy_hide_header 'access-control-allow-origin';
add_header 'access-control-allow-origin' '*';
  • 2
    I do not get it Aug 23, 2018 at 15:33
  • 2
    @Pierre.Vriens You hide the Access-Control-Allow-Origin that you get back from the server you proxy to with proxy_hide_header and then you add your own custom header with add_header. This answer is the only way to "replace" a header in Nginx as far as I know. Upvote from me!
    – Wilt
    Apr 15, 2019 at 14:54
  • I got proxy_hide_header directive is not allowed here so it is not working for me without further explanations...
    – m13r
    Feb 22, 2022 at 16:18
  • @m13r you cannot put proxy_hide_header inside an if block.
    – Zhang Buzz
    Feb 25, 2022 at 4:05

Folllow exe-dealer answer and if you are using php to set header you can make:

# always set a new header
add_header  access-control-allow-origin "*" always;

# remove header that came from php
fastcgi_hide_header access-control-allow-origin;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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