Skip to content

Instantly share code, notes, and snippets.

@weapp
Created August 4, 2014 17:21
Show Gist options
  • Save weapp/99049e69477f924dafa7 to your computer and use it in GitHub Desktop.
Save weapp/99049e69477f924dafa7 to your computer and use it in GitHub Desktop.
Return common errors as json in Nginx
error_page 500 /500.html;
location /500.html{
return 500 '{"error": {"status_code": 500,"status": "Internal Server Error"}}';
}
error_page 502 /502.html;
location /502.html{
return 502 '{"error": {"status_code": 502,"status": "Bad Gateway"}}';
}
error_page 503 /503.html;
location /503.html{
return 503 '{"error": {"status_code": 503,"status": "Service Temporarily Unavailable"}}';
}
error_page 504 /504.html;
location /504.html{
return 504 '{"error": {"status_code": 504,"status": "Gateway Timeout"}}';
}
error_page 400 /400.html;
location /400.html{
return 400 '{"error": {"status_code": 400,"status": "Bad Request"}}';
}
error_page 401 /401.html;
location /401.html{
return 401 '{"error": {"status_code": 401,"status": "Unauthorized"}}';
}
error_page 403 /403.html;
location /403.html{
return 403 '{"error": {"status_code": 403,"status": "Forbidden"}}';
}
error_page 404 /404.html;
location /404.html{
return 404 '{"error": {"status_code": 404,"status": "Not Found"}}';
}
error_page 408 /408.html;
location /408.html{
return 408 '{"error": {"status_code": 408,"status": "Request Timeout}}';
}
error_page 418 /418.html;
location /418.html{
return 418 '{"error": {"status_code": 418,"status": "I\'m a teapot"}}';
}
@eriadam
Copy link

eriadam commented Jan 18, 2019

You can also add the proper Content-Type to the header:

  error_page 500 /500.html;
  location /500.html {
    more_set_headers 'Content-Type: application/json charset=UTF-8';
    return 500 '{"error": {"status_code": 500,"status": "Internal Server Error"}}';
  }

@adonese
Copy link

adonese commented Apr 27, 2019

@eriadam more_set_headers is not working. Use add_header instead.
the syntax will be different though.

add_header 'Content-Type' 'application/json charset=UTF-8';

More here

@vinayan3
Copy link

If you set the file name endings json then the correct Content-Type header is generated. You can see that in the latest Nginx mime type file, https://github.com/nginx/nginx/blob/master/conf/mime.types.

@fragsalat
Copy link

Neither add_header nor more_set_headers worked for me.
I had to put default_type application/json; to tell nginx the content type is different from occet-stream

    location /this-is-now-an-error {
      default_type application/json;
      return 400 '{"error": "Because you get fired this is not allowed anymore"}';
    }

@wiseminds
Copy link

wiseminds commented Apr 27, 2020

for me i just changed .html to .json and it worked just fine.
for example

   error_page 404 /404.json;
    location /404.json{
    return 404 '{"error": {"status_code": 404,"status": "Not Found"}}';
    }

@JulienBreux
Copy link

JulienBreux commented Jul 8, 2020

My tiny contribution.

server {
    
    # your configuration here
    
    error_page 500 /500.json;
    location /500.json {
        return 500 '{"error":{"code":500,"message":"Internal Server Error"}}';
    }
    
    error_page 502 /502.json;
    location /502.json {
        return 502 '{"error":{"code":502,"message":"Bad Gateway"}}';
    }
    
    error_page 503 /503.json;
    location /503.json {
        return 503 '{"error":{"code":503,"message":"Service Temporarily Unavailable"}}';
    }
    
    error_page 504 /504.json;
    location /504.json {
        return 504 '{"error":{"code":504,"message":"Gateway Timeout"}}';
    }
    
    error_page 400 /400.json;
    location /400.json {
        return 400 '{"error":{"code":400,"message":"Bad Request"}}';
    }
    
    error_page 401 /401.json;
    location /401.json {
        return 401 '{"error":{"code":401,"message":"Unauthorized"}}';
    }
    
    error_page 403 /403.json;
    location /403.json {
        return 403 '{"error":{"code":403,"message": "Forbidden"}}';
    }
    
    error_page 404 /404.json;
    location /404.json {
        return 404 '{"error":{"code":404,"message":"Not Found"}}';
    }
    
    error_page 408 /408.json;
    location /408.json {
        return 408 '{"error":{"code":408,"message":"Request Timeout}}';
    }
    
    error_page 418 /418.json;
    location /418.json {
        return 418 '{"error":{"code":418,"message":"I\'m a teapot"}}';
    }
}

@mossad-zika
Copy link

@adonese more_set_headers workred for me

@KFoxder
Copy link

KFoxder commented Aug 15, 2021

@weapp

  1. Just a heads up that there is a missing " here: https://gist.github.com/weapp/99049e69477f924dafa7#file-nginx-conf-L44
error_page 408 /408.html;
location /408.html{
    return 408 '{"error": {"status_code": 408,"status": "Request Timeout"}}';
}
  1. If you don't want someone to be able to see these pages via an external request to /503.html for example you should use the internal; directive.
error_page 503 /503.html;
location /503.html{
    internal;
    add_header 'Content-Type' 'application/json charset=UTF-8';
    return 503 '{"error": {"status_code": 503,"status": "Service Temporarily Unavailable"}}';
}

@moozeek
Copy link

moozeek commented May 31, 2022

And here's a conf with all error codes as json

error_page 400 /400.json;
location /400.json {
    return 400 '{"error":{"code":400,"message":"Bad Request"}}';
}

error_page 401 /401.json;
location /401.json {
    return 401 '{"error":{"code":401,"message":"Unauthorized"}}';
}

error_page 402 /402.json;
location /402.json {
    return 402 '{"error":{"code":402,"message":"Payment Required"}}';
}

error_page 403 /403.json;
location /403.json {
    return 403 '{"error":{"code":403,"message":"Forbidden"}}';
}

error_page 404 /404.json;
location /404.json {
    return 404 '{"error":{"code":404,"message":"Not Found"}}';
}

error_page 405 /405.json;
location /405.json {
    return 405 '{"error":{"code":405,"message":"Method Not Allowed"}}';
}

error_page 406 /406.json;
location /406.json {
    return 406 '{"error":{"code":406,"message":"Not Acceptable"}}';
}

error_page 407 /407.json;
location /407.json {
    return 407 '{"error":{"code":407,"message":"Proxy Authentication Required"}}';
}

error_page 408 /408.json;
location /408.json {
    return 408 '{"error":{"code":408,"message":"Request Timeout"}}';
}

error_page 409 /409.json;
location /409.json {
    return 409 '{"error":{"code":409,"message":"Conflict"}}';
}

error_page 410 /410.json;
location /410.json {
    return 410 '{"error":{"code":410,"message":"Gone"}}';
}

error_page 411 /411.json;
location /411.json {
    return 411 '{"error":{"code":411,"message":"Length Required"}}';
}

error_page 412 /412.json;
location /412.json {
    return 412 '{"error":{"code":412,"message":"Precondition Failed"}}';
}

error_page 413 /413.json;
location /413.json {
    return 413 '{"error":{"code":413,"message":"Payload Too Large"}}';
}

error_page 414 /414.json;
location /414.json {
    return 414 '{"error":{"code":414,"message":"URI Too Long"}}';
}

error_page 415 /415.json;
location /415.json {
    return 415 '{"error":{"code":415,"message":"Unsupported Media Type"}}';
}

error_page 416 /416.json;
location /416.json {
    return 416 '{"error":{"code":416,"message":"Range Not Satisfiable"}}';
}

error_page 417 /417.json;
location /417.json {
    return 417 '{"error":{"code":417,"message":"Expectation Failed"}}';
}

error_page 418 /418.json;
location /418.json {
    return 418 '{"error":{"code":418,"message":"I\'m a Teapot"}}';
}

error_page 421 /421.json;
location /421.json {
    return 421 '{"error":{"code":421,"message":"Misdirected Request"}}';
}

error_page 422 /422.json;
location /422.json {
    return 422 '{"error":{"code":422,"message":"Unprocessable Entity"}}';
}

error_page 423 /423.json;
location /423.json {
    return 423 '{"error":{"code":423,"message":"Locked"}}';
}

error_page 424 /424.json;
location /424.json {
    return 424 '{"error":{"code":424,"message":"Failed Dependency"}}';
}

error_page 425 /425.json;
location /425.json {
    return 425 '{"error":{"code":425,"message":"Too Early"}}';
}

error_page 426 /426.json;
location /426.json {
    return 426 '{"error":{"code":426,"message":"Upgrade Required"}}';
}

error_page 428 /428.json;
location /428.json {
    return 428 '{"error":{"code":428,"message":"Precondition Required"}}';
}

error_page 429 /429.json;
location /429.json {
    return 429 '{"error":{"code":429,"message":"Too Many Requests"}}';
}

error_page 431 /431.json;
location /431.json {
    return 431 '{"error":{"code":431,"message":"Request Header Fields Too Large"}}';
}

error_page 451 /451.json;
location /451.json {
    return 451 '{"error":{"code":451,"message":"Unavailable For Legal Reasons"}}';
}

error_page 500 /500.json;
location /500.json {
    return 500 '{"error":{"code":500,"message":"Internal Server Error"}}';
}

error_page 501 /501.json;
location /501.json {
    return 501 '{"error":{"code":501,"message":"Not Implemented"}}';
}

error_page 502 /502.json;
location /502.json {
    return 502 '{"error":{"code":502,"message":"Bad Gateway"}}';
}

error_page 503 /503.json;
location /503.json {
    return 503 '{"error":{"code":503,"message":"Service Unavailable"}}';
}

error_page 504 /504.json;
location /504.json {
    return 504 '{"error":{"code":504,"message":"Gateway Timeout"}}';
}

error_page 505 /505.json;
location /505.json {
    return 505 '{"error":{"code":505,"message":"HTTP Version Not Supported"}}';
}

error_page 506 /506.json;
location /506.json {
    return 506 '{"error":{"code":506,"message":"Variant Also Negotiates"}}';
}

error_page 507 /507.json;
location /507.json {
    return 507 '{"error":{"code":507,"message":"Insufficient Storage"}}';
}

error_page 508 /508.json;
location /508.json {
    return 508 '{"error":{"code":508,"message":"Loop Detected"}}';
}

error_page 510 /510.json;
location /510.json {
    return 510 '{"error":{"code":510,"message":"Not Extended"}}';
}

error_page 511 /511.json;
location /511.json {
    return 511 '{"error":{"code":511,"message":"Network Authentication Required"}}';
}

@WhiteRabbit-Code
Copy link

Speed up the processing accordings to documenation:

error_page 400 /400.json;
location = /400.json {
    return 400 '{"error":{"code":400,"message":"Bad Request"}}';
}

error_page 401 /401.json;
location = /401.json {
    return 401 '{"error":{"code":401,"message":"Unauthorized"}}';
}

error_page 402 /402.json;
location = /402.json {
    return 402 '{"error":{"code":402,"message":"Payment Required"}}';
}

error_page 403 /403.json;
location = /403.json {
    return 403 '{"error":{"code":403,"message":"Forbidden"}}';
}

error_page 404 /404.json;
location = /404.json {
    return 404 '{"error":{"code":404,"message":"Not Found"}}';
}

error_page 405 /405.json;
location = /405.json {
    return 405 '{"error":{"code":405,"message":"Method Not Allowed"}}';
}

error_page 406 /406.json;
location = /406.json {
    return 406 '{"error":{"code":406,"message":"Not Acceptable"}}';
}

error_page 407 /407.json;
location = /407.json {
    return 407 '{"error":{"code":407,"message":"Proxy Authentication Required"}}';
}

error_page 408 /408.json;
location = /408.json {
    return 408 '{"error":{"code":408,"message":"Request Timeout"}}';
}

error_page 409 /409.json;
location = /409.json {
    return 409 '{"error":{"code":409,"message":"Conflict"}}';
}

error_page 410 /410.json;
location = /410.json {
    return 410 '{"error":{"code":410,"message":"Gone"}}';
}

error_page 411 /411.json;
location = /411.json {
    return 411 '{"error":{"code":411,"message":"Length Required"}}';
}

error_page 412 /412.json;
location = /412.json {
    return 412 '{"error":{"code":412,"message":"Precondition Failed"}}';
}

error_page 413 /413.json;
location = /413.json {
    return 413 '{"error":{"code":413,"message":"Payload Too Large"}}';
}

error_page 414 /414.json;
location = /414.json {
    return 414 '{"error":{"code":414,"message":"URI Too Long"}}';
}

error_page 415 /415.json;
location = /415.json {
    return 415 '{"error":{"code":415,"message":"Unsupported Media Type"}}';
}

error_page 416 /416.json;
location = /416.json {
    return 416 '{"error":{"code":416,"message":"Range Not Satisfiable"}}';
}

error_page 417 /417.json;
location = /417.json {
    return 417 '{"error":{"code":417,"message":"Expectation Failed"}}';
}

error_page 418 /418.json;
location = /418.json {
    return 418 '{"error":{"code":418,"message":"I\'m a Teapot"}}';
}

error_page 421 /421.json;
location = /421.json {
    return 421 '{"error":{"code":421,"message":"Misdirected Request"}}';
}

error_page 422 /422.json;
location = /422.json {
    return 422 '{"error":{"code":422,"message":"Unprocessable Entity"}}';
}

error_page 423 /423.json;
location = /423.json {
    return 423 '{"error":{"code":423,"message":"Locked"}}';
}

error_page 424 /424.json;
location = /424.json {
    return 424 '{"error":{"code":424,"message":"Failed Dependency"}}';
}

error_page 425 /425.json;
location = /425.json {
    return 425 '{"error":{"code":425,"message":"Too Early"}}';
}

error_page 426 /426.json;
location = /426.json {
    return 426 '{"error":{"code":426,"message":"Upgrade Required"}}';
}

error_page 428 /428.json;
location = /428.json {
    return 428 '{"error":{"code":428,"message":"Precondition Required"}}';
}

error_page 429 /429.json;
location = /429.json {
    return 429 '{"error":{"code":429,"message":"Too Many Requests"}}';
}

error_page 431 /431.json;
location = /431.json {
    return 431 '{"error":{"code":431,"message":"Request Header Fields Too Large"}}';
}

error_page 451 /451.json;
location = /451.json {
    return 451 '{"error":{"code":451,"message":"Unavailable For Legal Reasons"}}';
}

error_page 500 /500.json;
location = /500.json {
    return 500 '{"error":{"code":500,"message":"Internal Server Error"}}';
}

error_page 501 /501.json;
location = /501.json {
    return 501 '{"error":{"code":501,"message":"Not Implemented"}}';
}

error_page 502 /502.json;
location = /502.json {
    return 502 '{"error":{"code":502,"message":"Bad Gateway"}}';
}

error_page 503 /503.json;
location = /503.json {
    return 503 '{"error":{"code":503,"message":"Service Unavailable"}}';
}

error_page 504 /504.json;
location = /504.json {
    return 504 '{"error":{"code":504,"message":"Gateway Timeout"}}';
}

error_page 505 /505.json;
location = /505.json {
    return 505 '{"error":{"code":505,"message":"HTTP Version Not Supported"}}';
}

error_page 506 /506.json;
location = /506.json {
    return 506 '{"error":{"code":506,"message":"Variant Also Negotiates"}}';
}

error_page 507 /507.json;
location = /507.json {
    return 507 '{"error":{"code":507,"message":"Insufficient Storage"}}';
}

error_page 508 /508.json;
location = /508.json {
    return 508 '{"error":{"code":508,"message":"Loop Detected"}}';
}

error_page 510 /510.json;
location = /510.json {
    return 510 '{"error":{"code":510,"message":"Not Extended"}}';
}

error_page 511 /511.json;
location = /511.json {
    return 511 '{"error":{"code":511,"message":"Network Authentication Required"}}';
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment