I'm trying to display my sitemaps. Browsers display my sitemap index as xml but treat post sitemaps as plain text.

I tried to override content type with below configuration but it didn't help.

location ~ \.xml$ {
    proxy_hide_header Content-Type;
    add_header Content-Type "application/xml";

How do I force nginx to set content type as "application/xml" ?

Btw sitemaps in nutshell..

sitemap index

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">


and one of posts sitemaps

    <xhtml:link rel="alternate" hreflang="en" href="http://example.com/en" />
    <xhtml:link rel="alternate" hreflang="fr" href="http://example.com/fr" />

I use default laravel nginx configuration

  • Are you proxying connections upstream for static files? Why is proxy_hide_header in here? – Michael Hampton Feb 10 at 16:12
  • @MichaelHampton I don't actually. I tried with only "add_header" at first. But it didn't work then I saw that on nginx forum, someone advice that for my situation. – Hasan Tıngır Feb 10 at 16:59
  • What is the content type that was returned in the response? What was the URL? – Michael Hampton Feb 10 at 17:02
  • That's definitely the unexpected content-type. Please post the complete server block. – Michael Hampton Feb 10 at 17:13
  • @MichaelHampton I updated my question and added server bock – Hasan Tıngır Feb 10 at 17:20

You can't actually set the Content-Type header for proxy_passed content using plain nginx. You need to compile it with headers-more-nginx-module for that functionality. After you got that module, setting headers is as easy as:

location ~ \.xml$ {
    ... your config ...
    more_set_headers "Content-Type: application/xml";
    ... proxy_pass settings ...

Alternatively, if those sitemap files of yours are not actually generated by backend server on the fly and they actually exists in your website folder you don't really need to use proxy_pass. Try serving them directly by nginx instead with:

location ~ \.xml$ {
    try_files $uri =404;

If you don't know how to compile your nginx with external module on Ubuntu 18, just follow this simple steps:

  1. Become superuser with this command so we can skip typing sudo every time:

    sudo su

  2. Install prerequisites for building nginx by using the following command:

    apt install -y build-essential git tree libpcre3-dev libssl-dev zlib1g-dev libxslt1-dev libgd-dev libgeoip-dev

  3. Download latest nginx source from http://nginx.org/en/download.html

    wget http://nginx.org/download/nginx-1.15.8.tar.gz

  4. Unpack it & enter the source tree directory

    tar xzfv nginx-1.15.8.tar.gz && cd nginx-1.15.8

  5. Get the headers-more-nginx-module:

    git clone https://github.com/openresty/headers-more-nginx-module

  6. Get the configuration arguments of your installed nginx (by running nginx -V), add the --add-module=/path/to/headers-more-nginx-module option to them or just configure with the following command:

    ./configure --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --user=www-data --group=www-data --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/sbin/nginx --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module --add-module=./headers-more-nginx-module

  7. make && make install

  8. Now you have headers-more-nginx-module in your system & full support for those config directives, I mentioned earlier.

  • it throws unknown directive "more_set_headers" error – Hasan Tıngır Feb 10 at 14:23
  • @HasanTıngır Are you sure you've followed the installation procedure described on the github page? What distro do you use? – Anubioz Feb 10 at 15:51
  • I'm using ubuntu 18.04 and I used digital ocean documents while install lemp digitalocean.com/community/tutorials/… – Hasan Tıngır Feb 10 at 17:01
  • 1
    That version does not include the headers-more nginx module. You need to install that module by using the instructions indicated above. – Tero Kilkanen Feb 10 at 19:18
  • @HasanTıngır I added a step-by-step tutorial in case you don't know how to compile the module in... – Anubioz Feb 10 at 21:41

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.