The
break flag in Nginx rewrite rules stops the processing of further rewrite directives within the current location block and uses the modified URI for the next phase, such as file system lookup. It does not trigger a new location match or cause an internal redirect, which distinguishes it from the
last flag. Understanding this distinction is critical for configuring URL rewrites correctly without creating infinite loops or unintended behavior.
How Rewrite Flags Work
Nginx processes configuration files sequentially, evaluating directives based on their context. The
rewrite directive is powerful but can be confusing because its behavior changes depending on the flag used. When you place a
rewrite rule inside a
location block, the engine needs to know what to do with the new URI after the substitution. There are four main flags:
last,
break,
redirect, and
permanent. The two that operate internally are
last and
break. Confusing these two is a common source of 500 Internal Server Errors or unexpected 404 Not Found responses.
When Nginx encounters a rewrite rule, it modifies the request URI. The flag determines how the server handles that modified URI. If you use
break, the server stops executing any subsequent rewrite rules in the same location block. It then proceeds to the next phase of request processing, typically trying to find the file associated with the new URI on the disk. It does not restart the location matching process. This means the request stays within the same logical context unless the file lookup fails or leads elsewhere via other mechanisms like
try_files.
The Break Flag Specifically
The
break flag tells Nginx to stop processing the rewrite directives for the current request in the current context. After applying the rewrite, Nginx uses the rewritten URI to satisfy the request. For example, if you have a rule that maps
/app to
/index.php, using
break will cause Nginx to look for
/index.php in the document root immediately. It will not re-evaluate which
location block should handle
/index.php.
This is particularly useful when you want to map multiple URLs to a single script or file without triggering additional rewrite rules that might be defined later in the configuration or in nested locations. It effectively localizes the rewrite logic to the current block. If you were to omit the flag, Nginx would continue checking for more rewrite rules in the same location, which could lead to performance issues or incorrect mappings if other rules exist.
Consider a scenario where you have a complex set of rewrite rules for SEO-friendly URLs. You might want to normalize certain paths but ensure that the final mapping is handled by a specific PHP entry point. Using
break ensures that once the path is normalized, the control passes directly to the file handler or proxy pass, bypassing any further potential rewrites. This creates a predictable flow of execution.
For related configuration challenges, see
Nginx Configuration Issue for troubleshooting general setup errors.
Difference Between Break and Last
The most critical distinction is between
break and
last. Many users assume they are interchangeable, but they behave fundamentally differently regarding location matching. The
last flag stops the rewrite processing and causes Nginx to search for a new matching location block using the rewritten URI. This can result in the request being handled by a completely different
location context.
If you use
last, Nginx essentially restarts the location matching algorithm. For instance, if you rewrite
/old-page to
/new-page with
last, and you have a separate
location /new-page block, Nginx will jump to that block and evaluate its rules. This can lead to recursive loops if not configured carefully. In contrast,
break keeps the request in the original location block's scope for the purpose of locating the resource.
Using
last is appropriate when you need to redirect the request to a different logical section of your configuration. Using
break is appropriate when you just want to modify the URI for the current handler. A common mistake is using
last when
break is intended, which can cause performance degradation due to repeated location matching or even infinite loops if the new location contains similar rewrite rules.
Common Pitfalls and Best Practices
One frequent error is placing
rewrite rules in the wrong context. Rules placed in the
server block apply to all requests, while those in
location blocks only apply to specific paths. Using
break in a
server block can have wide-ranging effects. Always test your configuration with
nginx -t before reloading.
Another pitfall involves the order of rules. Nginx evaluates rewrite rules in the order they appear. If you have a catch-all rule at the end of a location block, earlier rules with
break will prevent it from ever executing. Ensure your most specific rules come first. Also, be aware that
break does not stop the execution of other non-rewrite directives like
proxy_pass or
root. It only halts the rewrite module's processing.
For insights on handling 404 errors during path resolution, refer to
NGINX X-Accel-Redirect 404 Error: Path Config Seems Correct.
Example Configuration
Here is a typical configuration demonstrating the use of the
break flag. This setup redirects all requests starting with
/api to a backend service, but first normalizes the URL structure.
server {
listen 80;
server_name example.com;
location /api/ {
# Normalize the URI by removing query parameters for logging purposes
rewrite ^/api/(.*)$ /api/$1 break;
# Proxy the request to the backend
proxy_pass http://backend_server;
}
}
In this example, the
rewrite directive modifies the URI but does not change the location context. The request continues to be handled by the
location /api/ block and is proxied accordingly. If
last were used, Nginx might try to find a new location block for the rewritten URI, potentially failing if no such block exists.
Frequently Asked Questions
Does break flag work in server context?
Yes, the
break flag works in the
server context as well as in
location blocks. However, using it in the
server context affects all requests processed by that server, so it should be used with caution to avoid unintended side effects on unrelated virtual hosts or paths.
What happens if I use last instead of break?
Using
last causes Nginx to restart the location matching process with the rewritten URI. This means the request may be handled by a different
location block than the one containing the rewrite rule. This can lead to different processing logic or errors if the new location does not exist or is misconfigured.
Can break cause infinite loops?
No, the
break flag itself does not cause infinite loops because it stops further rewrite processing in the current context. Infinite loops are more commonly caused by using
last incorrectly, where the rewritten URI matches the same location block again, causing repeated re-matching.
Should I use break or last for permanent redirects?
Neither
break nor
last is suitable for permanent redirects. For permanent redirects (HTTP 301), you should use the
permanent flag. For temporary redirects (HTTP 302), use the
redirect flag. These flags send an HTTP response to the client, whereas
break and
last are for internal processing.
Does break affect proxy_pass directives?
No, the
break flag only stops the processing of rewrite directives. It does not halt other directives like
proxy_pass,
root, or
alias. The request will continue to the next phase of processing, such as attempting to serve a file or proxying to a backend, based on the rewritten URI.