Skip to main content

On This Page

Fixing Server-Side Includes (SSI) in NGINX Gateway Fabric

2 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

How I Fixed an SSI-Breaking Bug in NGINX Gateway Fabric

Michael Uanikehi discovered a critical bug in NGINX Gateway Fabric that caused Server-Side Includes (SSI) to fail during infrastructure migrations. The root cause was identified as the immutable nature of the $request_uri variable, which forced internal subrequests to hit incorrect backend paths.

Why This Matters

In the transition from NGINX Ingress Controller to the Kubernetes Gateway API-based NGINX Gateway Fabric, subtle differences in NGINX configuration generation can break legacy features. This case demonstrates that while ideal models abstract complexity, technical reality requires a deep understanding of NGINX variables like $request_uri, which remains constant even during internal subrequests, potentially causing silent failures in SSI or authentication subrequests.

Key Insights

  • The $request_uri variable in NGINX is immutable across the entire request lifecycle, including internal subrequests (Uanikehi, 2026).
  • NGINX Gateway Fabric utilizes NJS-driven HTTP matching which requires internal redirects using r.internalRedirect to process matching rules.
  • External locations match client requests directly where $uri is already processed, making the use of $request_uri redundant and harmful for SSI.
  • The bug fix required a conditional check in the createProxyPass function to differentiate between External and Internal location types.
  • NGINX Gateway Fabric was verified using a local kind cluster to ensure proxy_pass directives no longer appended $request_uri for external locations.

Working Examples

A standard SSI pattern that triggers a subrequest for include.html.

<h1>SSI Test Page</h1>
<!--# include virtual="/include.html" -->

The logic change in internal/controller/nginx/config/servers.go ensuring $request_uri is only used for internal locations.

// Before fix
if !grpc {
    if filter == nil || filter.Path == nil {
        requestURI = "$request_uri"
    }
}

// After fix
if !grpc && locationType == http.InternalLocationType {
    if filter == nil || filter.Path == nil {
        requestURI = "$request_uri"
    }
}

Practical Applications

  • Migration from NGINX Ingress Controller to Gateway Fabric: System administrators must verify that SSI-enabled services do not have $request_uri appended to proxy_pass, which would otherwise ignore subrequest paths.
  • NJS-driven routing: Developers using NJS for complex matching must ensure that internal redirects correctly restore the client URI without breaking subrequest functionality in subsequent location blocks.

References:

Continue reading

Next article

Automating Google Colab with AI Agents: A Guide to colab-mcp and FastMCP

Related Content