Return JSON for 404 error instead of html

How can I return a custom JSON body on 404, instead of the default html
of:

<head>
    <title>404 Not Found</title>
</head>

<body bgcolor="white">
    <center>
        <h1>404 Not Found</h1>
    </center>
    <hr>
    <center>nginx</center>
</body>

Posted at Nginx Forum:

Justink101,

Using the echo module

error_page 404 @404;
location @404 { echo ‘{“status”: “Not Found”}’; }

On Mon, 12 May 2014, Lord N. wrote:

Justink101,

Using the echo module

error_page 404 @404;
location @404 { echo ‘{“status”: “Not Found”}’; }

if your using proxy_pass, don’t forget:

proxy_intercept_errors on;

Matthias

On Monday 12 May 2014 23:42:03 Lord N. wrote:

Justink101,

Using the echo module

error_page 404 @404;
location @404 { echo ‘{“status”: “Not Found”}’; }

[…]

Instead of using 3rd-party echo module, you can utilize the return
directive
for the same purpose:

return 200 ‘{“status”: “Not Found”}’;

Reference: Module ngx_http_rewrite_module

wbr, Valentin V. Bartenev

On Tuesday 13 May 2014 15:30:56 B.R. wrote:

​I would have intuitively written code 404 rather than 200 on this one
since the aim is to send a 404 error answer.​
Am I wrong? Would that loop?

I wrote an equivalent of “echo”. The logic is that in this handler we
provide
the page for 404 which actually exists.

wbr, Valentin V. Bartenev

​I would have intuitively written code 404 rather than 200 on this one
since the aim is to send a 404 error answer.​
Am I wrong? Would that loop?

B. R.

On Tuesday 13 May 2014 08:48:50 Justin D. wrote:

Out of curiosity, would the mime/content type show up as application/json
or text/plain?

It depends on the default_type directive:
http://nginx.org/r/default_type

wbr, Valentin V. Bartenev

Out of curiosity, would the mime/content type show up as
application/json
or text/plain?

Regards,

Justin D. http://www.twitter.com/jdorfman

Director of Developer Relations
MaxCDN http://twitter.com/MaxCDNDeveloper

Email / IM: [email protected]
Mobile: 818.485.1458
Twitter: @jdorfman http://www.twitter.com/jdorfman

application/octet-stream it is =p

Regards,

Justin D. http://www.twitter.com/jdorfman

Director of Developer Relations
MaxCDN http://twitter.com/MaxCDNDeveloper

Email / IM: [email protected]
Mobile: 818.485.1458
Twitter: @jdorfman http://www.twitter.com/jdorfman

On Tue, May 13, 2014 at 09:15:16PM +0200, B.R. wrote:

I understand the logic, but when using that handler through error_page 404
@404, won’t the handler’s 200 status overload the original 404 one?

Module ngx_http_core_module indicates that it won’t unless “=” is
used.

f

Francis D. [email protected]

I understand the logic, but when using that handler through error_page
404
@404, won’t the handler’s 200 status overload the original 404 one?


B. R.

Many thanks to both of you!
Another step in deeper understanding on how to use nginx. :o)

B. R.

Thanks for the replies and sorry about the delay in responding. This is
what
we ended up using:

error_page 404 = @four_o_four;

location @four_o_four {
internal;
more_set_headers “X-Host: web4.ourdomain.com”;
more_set_headers “Content-Type: application/json”;
return 404 ‘{“status”:“Not Found”}’;
}

Posted at Nginx Forum:

Noticed that the proxy request response headers are being thrown away in
our
404 block. Note that the proxied request is returning 404. If I try and
fetch a header that I know is being returned from the proxy it is
undefined.

location @four_o_four {
internal;
more_set_headers “X-Host: $sent_http_x_host”;
return 404 ‘{
“error”: {
“status_code”: 404,
“status”: “Not Found”,
“message”: “The requested resource does not exist.”
}
}’;
}

In our block example,x-host is being returned from the proxy response,
but
not visible in the @four_o_four location block. Any idea why?

Posted at Nginx Forum:

On Wed, May 14, 2014 at 06:38:45PM -0400, justink101 wrote:

Hi there,

If I try and
fetch a header that I know is being returned from the proxy it is
undefined.

location @four_o_four {
internal;
more_set_headers “X-Host: $sent_http_x_host”;

What value do you think $sent_http_x_host has, and why do you think
that?

Compare $http_name and $sent_http_name in
http://nginx.org/en/docs/http/ngx_http_core_module.html#variables
with $upstream_http_… in
http://nginx.org/en/docs/http/ngx_http_upstream_module.html#variables

and then use $upstream_http_x_host.

f

Francis D. [email protected]