Opened 10 months ago
Last modified 8 months ago
#2609 new defect
Custom 413 Error Page Not Displayed for Oversized Uploads
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-core | Version: | 1.25.x |
Keywords: | 413, custom error page, configuration, client_max_body_size | Cc: | |
uname -a: | Linux manager24.live 5.15.0-97-generic #107-Ubuntu SMP Wed Feb 7 13:26:48 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.25.4
built by gcc 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) built with OpenSSL 3.2.1 30 Jan 2024 TLS SNI support enabled configure arguments: --prefix=/home/manager24/nginx/ --http-client-body-temp-path=/home/manager24/tmp/client_temp --http-proxy-temp-path=/home/manager24/tmp/proxy_temp --http-fastcgi-temp-path=/home/manager24/tmp/fastcgi_temp --lock-path=/home/manager24/tmp/nginx.lock --http-uwsgi-temp-path=/home/manager24/tmp/uwsgi_temp --http-scgi-temp-path=/home/manager24/tmp/scgi_temp --conf-path=/home/manager24/nginx/conf/nginx.conf --error-log-path=/home/manager24/logs/error.log --http-log-path=/home/manager24/logs/access.log --pid-path=/home/manager24/nginx/nginx.pid --modules-path=/home/manager24/nginx/modules --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-threads --with-http_v2_module --with-mail --with-mail_ssl_module --with-file-aio --with-pcre-jit --with-compat --with-cpu-opt=generic --with-pcre=../pcre --with-zlib=../zlib --with-openssl=../openssl --with-http_v3_module --with-ld-opt='-Wl,-z,relro -Wl,--as-needed -L../boringssl/build/ssl -L../boringssl/build/crypto' --with-cc-opt='-static-libgcc -g -O2 -Wformat -Wall -I../boringssl/include' --add-dynamic-module=../ModSecurity-nginx --add-dynamic-module=../headers-more-nginx-module --add-dynamic-module=../ngx_brotli |
Description (last modified by )
I have configured Nginx to display a custom 413 error page when the client uploads a file that exceeds the allowed size limit. Despite the configuration, Nginx defaults to its built-in error page instead of displaying the specified custom error page.
Here is the relevant part of my Nginx configuration:
http { ... client_max_body_size 15m; ... server { ... error_page 413 /custom_413.html; location = /custom_413.html { root /home/xxx/error_page; internal; } } }
Expected Behavior: When a file larger than the allowed size is uploaded, Nginx should display the custom error page located at /home/xxx/error_page/custom_413.html.
Actual Behavior: Nginx displays its default error page for 413 errors, ignoring the custom error page configuration.
This issue persists even after ensuring that the client_max_body_size directive is properly set and the custom error page exists at the specified location.
Attachments (1)
Change History (11)
comment:1 by , 10 months ago
Description: | modified (diff) |
---|
comment:2 by , 10 months ago
Description: | modified (diff) |
---|
comment:3 by , 10 months ago
comment:4 by , 10 months ago
Thank you for your patience and assistance in addressing this issue. I've reviewed the Nginx configuration and found that it is correctly set up to redirect various HTTP error codes, including the 502 error, to our custom error page custom_default.html, as specified in the configuration:
error_page 404 /index.php;
error_page 400 401 403 405 408 413 429 500 501 502 503 504 507 /custom_default.html;
location = /custom_default.html {
root /home/xxx/error_page;
internal;
}
Interestingly, this redirection works as expected when a 502 error occurs, for example, by stopping PHP, thus provoking such an error. The request is correctly redirected to custom_default.html.
However, I have noticed that for an upload exceeding the maximum file size, which should trigger a 413 error, the redirection does not work as expected. Although Nginx aborts the upload as intended, it does not redirect to custom_default.html.
I also attempted isolating the issue by configuring the redirection specifically for the 413 error code alone, to exclude any potential conflicts or errors. Despite this targeted approach, the redirection to custom_default.html for the 413 error scenario did not occur as expected.
I would like to add, on a professional note, that while this issue is not of personal significance to me, I believe it may represent a flaw within the handling or configuration of error redirection in Nginx, particularly for the 413 error code. I felt it was important to report this observation, in the interest of continuous improvement and to assist in identifying potential areas for enhancement.
comment:5 by , 10 months ago
Again, please make sure you do not override error_page
in inner scopes in your configuration, for example in your location{}
blocks.
server { error_page 413 /foo; # set up an error page for 413 location / { error_page 400 /bar; # this directive cancels the above one for this location .. } }
Redirecting the 413 error works fine for me in a simple test case. If it does not work in your config, could you please provide a minimum configuration where this problem occurs.
comment:6 by , 10 months ago
exactly with this config i can provoke a 502 error and i get redirected to the custom_default. when i upload a large file the one from nginx appears and not the custom_default.
user xxx; worker_processes auto; load_module modules/ngx_http_headers_more_filter_module.so; load_module modules/ngx_http_brotli_filter_module.so; load_module modules/ngx_http_brotli_static_module.so; worker_rlimit_nofile 300000; events { worker_connections 16000; use epoll; accept_mutex on; multi_accept on; } thread_pool pool_xxx threads=12 max_queue=64; http { more_set_headers 'Server: xxxlive'; more_clear_headers 'X-Powered-By'; include mime.types; default_type application/octet-stream; sendfile on; tcp_nopush on; tcp_nodelay on; reset_timedout_connection on; brotli on; brotli_comp_level 4; brotli_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript; brotli_static on; gzip on; gzip_vary on; gzip_proxied any; gzip_disable "msie6"; gzip_http_version 1.1; gzip_min_length 2048; gzip_buffers 32 16k; gzip_comp_level 4; gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript; open_file_cache max=1000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; fastcgi_read_timeout 200; access_log /home/xxx/logs/access.log; keepalive_timeout 10; include balance.conf; send_timeout 20m; sendfile_max_chunk 512k; lingering_close off; aio threads=pool_xxx; client_body_timeout 13s; client_header_timeout 13s; client_max_body_size 10m; client_body_buffer_size 10m; client_header_buffer_size 1k; large_client_header_buffers 4 16k; etag on; server_tokens off; proxy_cache_bypass $http_pragma; limit_req_zone $binary_remote_addr zone=one:60m rate=50r/s; server { listen 80 default_server; listen [::]:80 default_server; location / { return 301 https://$host$request_uri; } } server { server_name panel.xxx.live; listen 443 quic reuseport; listen [::]:443 quic reuseport; listen 443 ssl; listen [::]:443 ssl; http2 on; quic_retry on; quic_gso on; ssl_certificate fullchain.pem; ssl_certificate_key privkey.pem; ssl_trusted_certificate chain.pem; ssl_dhparam dhparam.pem_4096; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; ssl_ocsp on; ssl_protocols TLSv1.3 TLSv1.2; ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256'; ssl_prefer_server_ciphers off; add_header Alt-Svc 'h3=":$server_port"; ma=86400'; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; add_header X-Request-ID $request_id; add_header X-Frame-Options DENY always; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options nosniff always; add_header Referrer-Policy 'same-origin' always; add_header Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(self),camera=(self),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()" always; proxy_cookie_flags ~ secure samesite=strict; resolver 1.1.1.1 valid=300s; resolver_timeout 5s; index index.php index.html index.htm; root /home/xxx/panel/public; chunked_transfer_encoding off; charset utf-8; location / { try_files $uri $uri/ /index.php?$query_string; } location ~* \.(jpg|jpeg|gif|png|svg|ico|css|woff2|js)$ { add_header Cache-Control "public, max-age=31536000"; } error_page 400 401 403 405 408 413 429 500 501 502 503 504 507 /custom_default.html; location = /custom_default.html { root /home/xxx/error_page; internal; } location ~ \.php$ { limit_req zone=one burst=20 nodelay; try_files $uri /index.php =404; fastcgi_index index.php; fastcgi_pass php; include fastcgi_params; fastcgi_buffering on; fastcgi_buffers 96 32k; fastcgi_buffer_size 32k; fastcgi_max_temp_file_size 0; fastcgi_keep_conn on; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; } } }
comment:7 by , 10 months ago
Thanks a lot for your config. I reproduced the issue. It only happens with http/2 and http/3. Please try the attached patch which should fix it.
by , 10 months ago
Attachment: | h23-discard-body added |
---|
comment:8 by , 10 months ago
I wanted to extend my sincere gratitude for providing the patch regarding the HTTP/2 and HTTP/3 issue with the custom 413 error page. I have applied the patch as instructed, and I'm pleased to report that it has successfully resolved the issue on my end.
Thank you once again for your dedication and support.
Best regards
comment:9 by , 8 months ago
Hello Team,
I wanted to inform you that the patch h23-discard-body, which was provided to address the issue with the custom 413 error page on HTTP/2 and HTTP/3, has not been incorporated into the latest version 1.25.5. I had to reapply the patch to resolve the issue in this current version.
Could you please check if it is feasible to permanently include this patch in an upcoming release? This would greatly simplify implementation for us and other users.
Thank you for your support and dedication.
Best regards
comment:10 by , 8 months ago
It's true, the patch has not been committed yet. We are still evaluating this solution and also considering alternative approaches.
Overall your conf snippet looks right. However make sure you do not override
error_page
in the inner scopes of your full config. For example if you have anerror_page
in the location that processes your request, it will cancel the error page for 413.https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page:
These directives are inherited from the previous configuration level if and only if there are no error_page directives defined on the current level.