203

I have configured Apache to send back a 200 response without serving any file with this configuration line

Redirect 200 /hello

Can I do this with Nginx? I don't want to serve a file, I just want the server to respond with a 200 (I'm just logging the request).

I know I can add an index file and achieve the same thing, but doing it in the config means there's one less thing that can go wrong.

1
  • 1
    One could argue that if you don't serve a "file" or any content, you should return 204 No Content, as opposed to 200.
    – amn
    Aug 6 '20 at 13:21
403

Yes, you can

location / {
    return 200 'gangnam style!';
    # because default content-type is application/octet-stream,
    # browser will offer to "save the file"...
    # if you want to see reply in browser, uncomment next line 
    # add_header Content-Type text/plain;
}
12
  • 2
    how do I add a newline to the response? gangnam\nstyle?
    – tback
    Dec 28 '15 at 13:52
  • 3
    @tback of course, right you are
    – cadmi
    Mar 9 '16 at 9:10
  • 8
    add_header doesn't work for me as it adds another header instead of replacing the old 'Content-type'. In my response I have 2 'Content-type' headers:$ curl -v localhost/healthcheck/h1_pio > GET /healthcheck/h1_pio HTTP/1.1 > User-Agent: curl/7.38.0 > Host: localhost > Accept: / > < HTTP/1.1 200 OK < Date: Tue, 11 Oct 2016 13:27:53 GMT < Content-Type: application/octet-stream < Content-Length: 25 < Connection: keep-alive < Content-Type: application/json
    – jmcollin92
    Oct 11 '16 at 13:30
  • 8
    @jmcollin92 that can happen if you have an existing default_type declared somewhere else. You can override it by using default_type text/plain; inside of the location block in place of the add_header directive.
    – tjb1982
    May 23 '17 at 17:55
  • 3
    Hint: use add_header Content-Type text/plain always; to force plain text if you're not returning a "successful" code.
    – Tugzrida
    Mar 15 '19 at 13:25
31

You do need to use a 204 as Nginx will not allow a 200 with no response body. To send a 204 you simply use the return directive to return 204; in the appropriate location.

1
  • 1
    If you try to view this through a browser, it will look like it did nothing. that's intentional. You served nothing (204), it displays nothing. To prove you served a 204, use curl.
    – jnovack
    Mar 19 '19 at 18:23
21

If you want to return a formatted HTML text, without serving a HTML file:

location / {
    default_type text/html;
    return 200 "<!DOCTYPE html><h2>gangnam style!</h2>\n";
}

If you want to return a text without html format, as the answer points:

location / {
    add_header Content-Type text/plain;
    return 200 'gangnam style!';
}

And if you just simply wants to return 200:

location / {
    return 200;
}

Just to remember: location blocks go inside server blocks. Here's a doc for more info.

P.S.: I have similar configuration (formatted html) runnning on plenty of servers.

7

To complete @Martin Fjordval's answer, be careful if you're using such a configuration to do a healthcheck.

While a 204 HTTP code is semantically perfect for a healthcheck (success indication with no content), some services do not consider it a success.

Namely, I had the issue with Google Cloud Load-balancers.

1
  • Exactly. Google Cloud Load Balancer requires a 200 response code to consider the instance healthy, no matter the body. Any other code (even 2xx codes) will make the health check fail.
    – maganap
    Mar 18 '20 at 14:56
6

As per status code definitions, I believe you want it to be a 204, and not 200. 200's need to be with a resource in the response, or I'd suspect most sane browsers would get confused by this. The other one you can use is 304, which is for cached content.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

3
  • Sure, make it a 204, how do I do it? Although I very much doubt any browser will be confused by an empty body.
    – Theo
    Nov 1 '10 at 15:55
  • 2
    an empty body is still a response, with an object, such as a blank index.html. What you asked is to provide a 200 response with no resource attached to it (no file served). As for how exactly to do it on nginx, I need to look it up myself, I've only once done this on apache, and I can't remember off hand.
    – sandroid
    Nov 1 '10 at 20:05
  • 304 seems like it would send all the wrong signals for things like debugging and temporary returns.
    – Kzqai
    Feb 5 '16 at 20:18
2

Expanding on the @cadmi answer for a specific case of Kubernetes ingress-nginx controller configuration.

In my case, I could only append the small part of the Nginx configuration inside the location directive.

I wanted to add a custom 404 error JSON message for a specific if directive. Since default_type is not allowed inside the if directive I came up with adding the "blank" default_type outside the if directive and add_header inside the if directive:

http {
    default_type text/html; # can't change this
    ...
    server {
        ...
        location / {
            ...
            # This part of configuration is something I can change (generated by ingress-nginx controller `ingress.kubernetes.io/configuration-snippet` annotation)
            default_type "";
            # Custom 404 JSON page returned for the call to my.specific.host
            if ($host = my.specific.host) {
                return 404 '{\n  "status": "404",\n  "message": "Not Found",\n  "details": "Please call other hosts."\n}\n';
                add_header Content-Type "application/json" always;
            }
        }
    }
}

Without the default_type ""; an add_header directive was adding the second Content-Type header instead of changing the default one.

1
  • If you have nginx-extras, openresty or similar, you don't need default_type ""; - just use more_set_headers 'Content-Type: text/plain'; - plus return 900 'blubbi'.
    – uav
    Aug 5 at 11:57

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.