https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/ < Your Cookie Settings Analytics cookies are off for visitors from the UK or EEA unless they click Accept or submit a form on nginx.com. They're on by default for everybody else. Follow the instructions here to deactivate analytics cookies. This deactivation will work even if you later click Accept or submit a form. [ ] Check this box so we and our advertising and social media partners can use cookies on nginx.com to better tailor ads to your interests. Uncheck it to withdraw consent. Cookie preferences Accept cookies for analytics, social media, and advertising, or learn more and adjust your preferences. These cookies are on by default for visitors outside the UK and EEA. Privacy Notice. Accept Web Server Load Balancing with NGINX Plus * Free Trial * Contact Us Web Server Load Balancing with NGINX Plus * Products + NGINX Plus + NGINX Controller + NGINX App Protect + NGINX Unit + NGINX Amplify * Solutions + ADC / Load balancing + Microservices + Cloud + Security + Web & Mobile Performance + API Management * Resources + Documentation + Ebooks + Webinars + Datasheets + Success Stories + FAQ + Learn + Glossary + Third Party Integrations * Support + NGINX Plus Support + Training + Professional Services + Customer Portal Login * Pricing * Blog Search [ ] [Search] 1-800-915-9122 Search [ ] [Search] Navigation * next * previous | * NGINX >> * Getting Started >> If is Evil... when used in location context If is Evil... when used in location contextP IntroductionP Directive if has problems when used in location context, in some cases it doesn't do what you expect but something completely different instead. In some cases it even segfaults. It's generally a good idea to avoid it if possible. The only 100% safe things which may be done inside if in a location context are: * return ...; * rewrite ... last; Anything else may possibly cause unpredictable behaviour, including potential SIGSEGV. It is important to note that the behaviour of if is not inconsistent, given two identical requests it will not randomly fail on one and work on the other, with proper testing and understanding ifs '''can''' be used. The advice to use other directives where available still very much applies, though. There are cases where you simply cannot avoid using an if, for example, if you need to test a variable which has no equivalent directive. if ($request_method = POST ) { return 405; } if ($args ~ post=140){ rewrite ^ http://example.com/ permanent; } What to do insteadP Use try_files if it suits your needs. Use the "return ..." or "rewrite ... last" in other cases. In some cases, it's also possible to move ifs to server level (where it's safe as only other rewrite module directives are allowed within it). E.g. the following may be used to safely change location which will be used to process request: location / { error_page 418 = @other; recursive_error_pages on; if ($something) { return 418; } # some configuration ... } location @other { # some other configuration ... } In some cases it may be good idea to use embedded scripting modules ( embedded perl, or various NGINX 3rd Party Modules) to do the scripting. ExamplesP Here are some examples which explain why if is evil. Don't try this at home. You were warned. # Here is collection of unexpectedly buggy configurations to show that # if inside location is evil. # only second header will be present in response # not really bug, just how it works location /only-one-if { set $true 1; if ($true) { add_header X-First 1; } if ($true) { add_header X-Second 2; } return 204; } # request will be sent to backend without uri changed # to '/' due to if location /proxy-pass-uri { proxy_pass http://127.0.0.1:8080/; set $true 1; if ($true) { # nothing } } # try_files wont work due to if location /if-try-files { try_files /file @fallback; set $true 1; if ($true) { # nothing } } # nginx will SIGSEGV location /crash { set $true 1; if ($true) { # fastcgi_pass here fastcgi_pass 127.0.0.1:9000; } if ($true) { # no handler here } } # alias with captures isn't correcly inherited into implicit nested # location created by if location ~* ^/if-and-alias/(?.*) { alias /tmp/$file; set $true 1; if ($true) { # nothing } } In case you think you found an example which isn't listed here - it's a good idea to report it to the NGINX development mailing list. Why this happens and still not fixedP Directive "if" is part of rewrite module which evaluates instructions imperatively. On the other hand, NGINX configuration in general is declarative. At some point due to users demand an attempt was made to enable some non-rewrite directives inside "if", and this lead to situation we have now. It mostly works, but... see above. Looks like the only correct fix would be to disable non-rewrite directives inside if completely. It would break many configuration out there though, so wasn't done yet. If you still want to use if inside location contextP If you read all of the above and still want to use if: * Please make sure you actually do understand how it works. Some basic idea may be found e.g. here. * Do proper testing. You were warned. [ ] [] Wiki home * Getting Started + Dynamic SSI Example + Full Example Configuration + Another Full Example + Simple Load Balancing + Reverse Proxy with Caching + SSL-Offloader + Log Rotation + Server Block Examples + PHP FastCGI Example + PHP-FastCGI on Windows + Dispatching TurboGears Python via FCGI + Simple Ruby FCGI + Django FastCGI + FCGI Wrap + FastCGI Example + Java servers like Jetty, GlassFish and Tomcat + Mono FCGI + X-Accel + NGINX Solution for Apache ProxyPassReverse + Like Apache: .htaccess + Separating Error Logs per Virtual Host + IMAP Proxy Example + Using a Perl Script as the IMAP Auth Backend + Using a PHP Script on an Apache Server as the IMAP Auth Backend + Non-root Web Path + Managing request headers + A flexibility of the HTTP headers + Get a header value + How can I set a header? + PiotrSikora + Examples + NGINX Init Scripts + Hardware Loadbalancer Check Errors + XSendfile + Memcache Preload + Embedded Perl Minify JS + Embedded Perl Sitemaps Proxy + Using the Forwarded header + CMS Made Simple + Codeigniter + Drupal + Dokuwiki + Elgg + ExpressionEngine + Geth (go-ethereum) + iRedMail + Mailman + MediaWiki + MoinMoin + MyBB + Omeka-s + Omeka + osCommerce + osTicket + PHPList + Matomo + PmWiki + Pylons + PyroCMS + Qwebric + Redmine + SilverStripe + SPIP + Symfony + Another working symfony + WordPress + XenForo + Yii + Zend Framework + Zenphoto + Zope via FastCGI + b2evolution + UVdesk + Shopware + Bagisto + Krayin + QloApps + If is Evil... when used in location context o Introduction o What to do instead o Examples o Why this happens and still not fixed o If you still want to use if inside location context + Getting Started + Install + Installation and Compile-Time Options + CommandLine + Pitfalls and Common Mistakes + Debugging + Optimizations + Installing on Solaris 10u5 + Testing NGINX + Running NGINX as SMF service + Installing on Solaris 11 + Startup script + Installing and configuring NGINX / Mongrel on OpenBSD with Rails support + Installing & Configuring NGINX + Full Stack HOWTOs + Pre-canned Configurations + Other Examples + Tools + Advanced Topics + Learning Resources * Community * NGINX 3^rd Party Modules * Extending NGINX [ ] [] Stay in the Loop Edit this page * Show on GitHub * Edit on GitHub Navigation * next * previous | * NGINX >> * Getting Started >> * Products + NGINX Plus + NGINX Controller + NGINX App Protect + NGINX Unit + NGINX Amplify * NGINX on Github + NGINX Open Source + NGINX Unit + NGINX Amplify + NGINX Kubernetes Ingress Controller + NGINX Microservices Reference Architecture + NGINX Crossplane * Solutions + ADC / Load Balancing + Microservices + Cloud + Security + Web & Mobile Performance + API Management * Resources + Documentation + Ebooks + Webinars + Datasheets + Success Stories + Blog + FAQ + Learn + Glossary * Support + Professional Services + Training + Customer Portal Login * Partners + Amazon Web Services + Google Cloud Platform + IBM + Microsoft Azure + Red Hat + Find a Partner + Certified Module Program * Company + About NGINX + Careers + Leadership + Press + Events Connect With Us * facebook * twitter * linkedin * NGINX Youtube Channel * rss Stay in the Loop Copyright (c) F5, Inc. All rights reserved. | Privacy Policy | Cookie Choices