40

Is it possible to have the 40x and 50x errors served by a single location rule? Something like:

error_page 403 /403.html;
error_page 404 /404.html;
error_page 405 /405.html;
error_page 500 501 502 503 504 /5xx.html;

location ~ /(?:40[345]|5xx)[.]html$ {
    root /var/www/default/error;
}

2 Answers 2

104
error_page 403 /error/403.html;
error_page 404 /error/404.html;
error_page 405 /error/405.html;
error_page 500 501 502 503 504 /error/5xx.html;

location ^~ /error/ {
    internal;
    root /var/www/default;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Excellent solution. In case anyone is totally new to this, note that you still need to create the "error" folder inside /var/www/default
...or use alias instead of root, and then the files will be read directly from /var/www/default/, instead of /var/www/default/error/.
I wanted to have a server block that would respond to any server names not configured (so on e.g. IP address a 404 page would be served). I want that page to be custom. I wrote: listen 80 default_server; server_name default; return 404; error_page 404 /errors/404.html; location ^~ /errors/ { internal; root /var/www; }. I still get default nginx 404 error page. Does return 404; work with custom pages?
Hint: if your error page is using static files like images/css/... from the same directory then omit internal;
1

A dynamic HTTP response page can respond to all HTTP response codes defined in the Nginx source code src/http/ngx_http_header_filter_module.c.

## Nginx source code file to extract HTTP response codes from
$ NGINX_SRC_URL="https://raw.githubusercontent.com/nginx/nginx/master/src/http/ngx_http_header_filter_module.c"

### Find values double quotes that match lines 'ngx_string("### '
$ curl --silent $NGINX_SRC_URL | egrep 'ngx_string\(\"[0-9]{3} .*\"' | cut -d\" -f2 | sort

# OUTPUTS
200 OK
201 Created
202 Accepted
...

Nginx Config

# in http {} block

error_page
  301 302 303 304 307 308
  400 401 402 403 404 405 406 408 409 410 411 412 413 414 415 416 421 429
  500 501 502 503 504 505 507
  @errors;

map $status $status_text {
  default "Unknown error";
  200 "OK";
  201 "Created";
  202 "Accepted";
  204 "No Content";
  206 "Partial Content";
  301 "Moved Permanently";
  302 "Moved Temporarily";
  303 "See Other";
  304 "Not Modified";
  307 "Temporary Redirect";
  308 "Permanent Redirect";
  400 "Bad Request";
  401 "Unauthorized";
  402 "Payment Required";
  403 "Forbidden";
  404 "Not Found";
  405 "Not Allowed";
  406 "Not Acceptable";
  408 "Request Time-out";
  409 "Conflict";
  410 "Gone";
  411 "Length Required";
  412 "Precondition Failed";
  413 "Request Entity Too Large";
  414 "Request-URI Too Large";
  415 "Unsupported Media Type";
  416 "Requested Range Not Satisfiable";
  421 "Misdirected Request";
  429 "Too Many Requests";
  500 "Internal Server Error";
  501 "Not Implemented";
  502 "Bad Gateway";
  503 "Service Temporarily Unavailable";
  504 "Gateway Time-out";
  505 "HTTP Version Not Supported";
  507 "Insufficient Storage";
}
##  in server {} block

location @errors {
  internal;
  default_type "text/plain; charset=utf-8";
  return 200 "$status $status_text\n";
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.