#2304 closed defect (invalid)
error_page not applied vs Transfer-Encoding: chunked
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-core | Version: | 1.19.x |
Keywords: | error_page | Cc: | ilsixela@… |
uname -a: | Linux gateway-79fdb46457-69njm 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64 Linux | ||
nginx -V: |
nginx version: nginx/1.21.5
built by gcc 10.3.1 20211027 (Alpine 10.3.1_git20211027) built with OpenSSL 1.1.1l 24 Aug 2021 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --with-perl_modules_path=/usr/lib/perl5/vendor_perl --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-Os -fomit-frame-pointer -g' --with-ld-opt=-Wl,--as-needed,-O1,--sort-common |
Description
I've configured an error page in Nginx:
error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 421 422 423 424 425 426 428 429 431 451 495 496 497 500 501 502 503 504 505 506 507 508 510 511 /error.html; location = /error.html { ssi on; internal; auth_basic off; root /etc/nginx; }
This works fine for a 404. However I'm submitting a request like this:
POST /graphql HTTP/1.1 Content-Length: 2 Transfer-Encoding: chunked Connection: close {}
Note Transfer-Encoding: chunked. Nginx returns a 400 Bad Request error page of its own instead of mine. One minor clue is that the footer only says "nginx", it doesn't include a version. I tried adding "server_tokens off;" and it didn't change anything.
How do I make Nginx use my error page for ALL errors, please?
Change History (3)
comment:1 by , 3 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 3 years ago
Thank you very much for your response! Please could I see the config you used to test with?
This is my full config, I'm no expert but I'm pretty sure I'm applying the error_page to the default server? The presence of a Host header made no difference from Burp but it does change with curl - no host gives me the 400 Bad Request, with host I get 401 Unauthorized. Also tried with telnet, see below.
events {} http { server { listen 80; auth_request /authorise; server_tokens off; location = /ping { return 200; } error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 421 422 423 424 425 426 428 429 431 451 495 496 497 500 501 502 503 504 505 506 507 508 510 511 /error.html; location = /error.html { ssi on; internal; auth_basic off; root /etc/nginx; } location = /authorise { internal; proxy_pass_request_body off; proxy_set_header Content-Length 0; proxy_http_version 1.1; proxy_pass --elided to avoid "external link"-- } location /graphql { auth_request_set $auth_token $upstream_http_authorization; proxy_set_header Authorization $auth_token; proxy_http_version 1.1; proxy_pass --elided to avoid "external link"-- } location /subscriptions { auth_request_set $auth_token $upstream_http_authorization; proxy_set_header Authorization $auth_token; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; proxy_http_version 1.1; proxy_pass --elided to avoid "external link"-- } } }
Telnet output, no host:
$ telnet tempest.minikube 80 Trying 192.168.49.2... Connected to tempest.minikube. Escape character is '^]'. POST /graphql HTTP/1.1 Content-Length: 2 Transfer-Encoding: chunked Connection: close HTTP/1.1 400 Bad Request Date: Fri, 14 Jan 2022 13:43:59 GMT Content-Type: text/html Content-Length: 150 Connection: close <html> <head><title>400 Bad Request</title></head> <body> <center><h1>400 Bad Request</h1></center> <hr><center>nginx</center> </body> </html> Connection closed by foreign host.
With Host header:
$ telnet tempest.minikube 80 Trying 192.168.49.2... Connected to tempest.minikube. Escape character is '^]'. POST /graphql HTTP/1.1 Host: tempest.minikube Content-Length: 2 Transfer-Encoding: chunked Connection: close HTTP/1.1 400 Bad Request Date: Fri, 14 Jan 2022 13:47:34 GMT Content-Type: text/html Content-Length: 150 Connection: close <html> <head><title>400 Bad Request</title></head> <body> <center><h1>400 Bad Request</h1></center> <hr><center>nginx</center> </body> </html> Connection closed by foreign host.
I tried to test with 1.21.6 but I don't think that's available yet, not as an Alpine container at least.
comment:3 by , 3 years ago
Please could I see the config you used to test with?
I've used the exact configuration you've provided with minimal required additions/modifications:
events { } http { server { listen 8080; error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 421 422 423 424 425 426 428 429 431 451 495 496 497 500 501 502 503 504 505 506 507 508 510 511 /error.html; location = /error.html { ssi on; internal; auth_basic off; root /tmp/; } } }
I tried to test with 1.21.6 but I don't think that's available yet, not as an Alpine container at least.
It's a version from the mainline branch, it's basically the same as 1.21.5 and no different from any other nginx version when it comes to the problem you are trying to debug.
First of all you may want to check that you are connecting to nginx directly, without any intermediate proxies, and that the configuration you are editing is the actual configuration being used.
Work fine here:
Make sure you are configuring error pages in the default server, and not a name-based virtual servers: your request doesn't contain the "Host" header and the error will be generated in the context of the default server.
Note well that it might not be a good idea to configure custom error pages for low-level errors such as 400: these errors happen at early stages of request processing and some of the request properties might not be set, potentially resulting in unexpected behaviour.
With "server_tokens off;" default error pages (and the Server response header) are expected to contain "nginx" without a version. With "server_tokens on;" (the default) there will be "nginx/<version>", see docs.