Skip to content

TrafficProtectionPolicy Enforce mode: 500 with truncated/empty body on all traffic #242

Description

@kevwilliams

Summary

TrafficProtectionPolicy (TPP) in Enforce mode causes a 100% reproducible 500 with a truncated response body, on a plain HTTPProxy with no unusual traffic (small static page, GET /, no request body). Disabling the TPP fixes it immediately.

Environment

  • Project: default-ec6p8s
  • Proxy: kev1n-proxy (HTTPProxy -> Gateway/HTTPRoute -> edge hostname 52f1481fa40341799b03b2bd02432592.datumproxy.net)
  • Backend: https://kev1n-org.vercel.app (static Vercel-hosted site, 2408-byte HTML response)
  • TrafficProtectionPolicy spec:
    apiVersion: networking.datumapis.com/v1alpha
    kind: TrafficProtectionPolicy
    spec:
      mode: Enforce
      ruleSets:
      - type: OWASPCoreRuleSet
        owaspCoreRuleSet:
          paranoiaLevels: {detection: 1, blocking: 2}
          scoreThresholds: {inbound: 5, outbound: 4}
      targetRefs:
      - group: gateway.networking.k8s.io
        kind: Gateway
        name: kev1n-proxy
  • TPP status: Accepted=True (policy is correctly attached, not a translation/acceptance failure)

Repro

$ curl -v https://52f1481fa40341799b03b2bd02432592.datumproxy.net/
< HTTP/1.1 500 Internal Server Error
< content-length: 13001
< content-type: text/html; charset=UTF-8
<
* TLS alert, close notify
* end of response with 13001 bytes missing
curl: (18) end of response with 13001 bytes missing
  • 100% reproducible across 5+ consecutive requests.
  • Direct-to-origin (curl https://kev1n-org.vercel.app/) returns a clean 200, 2408-byte body.
  • Content-Length: 13001 does not match the origin's real body size (2408 bytes) — it's suspected to be the size of the NSO extension server's branded 5xx error page (errorPage.bodyPath: /etc/datum/error-pages/error-5xx.html in the Coraza config), but zero bytes of any body are actually delivered before the connection closes.
  • Disabling the TPP (deleting/detaching it from the Gateway) immediately restores normal 200 responses with the full 2408-byte body.

Isolation performed

To rule out a filter-chain interaction, I removed the HTTPProxy's own ResponseHeaderModifier filter (which adds an x-kevin-test response header) while leaving the TPP in Enforce mode:

  • Before: response included x-kevin-test: true header, then 500 / Content-Length: 13001 / 0 bytes delivered.
  • After removing the filter: x-kevin-test header confirmed gone (change propagated), but identical failure signature persisted — same 500, same Content-Length: 13001, same 0 bytes delivered.

This rules out interaction with other Gateway API filters (ResponseHeaderModifier) as the cause. The failure is isolated to the TPP/Coraza WAF path itself — likely a bug in how the extension server (or the underlying coraza-envoy-go-filter, currently pinned at v1.3.0-alpha4 — an alpha release) computes/sends the branded error-page Content-Length header without actually writing the corresponding body to the response, leaving the client with a truncated/incomplete response.

Given the response body here is small (2408 bytes, well under any sane SecResponseBodyLimit) and the request has no body at all (GET /), this does not appear to be a body-size-limit rejection (which was previously fixed for the response-body case in 888f22f0f, "fix: 500 response body over limit issue") — it looks like a distinct defect in the error-page/local-reply body-write path.

Suggested places to look

  • apps/network-services-operator/downstream/base/extension-server-config.yamlgateway.errorPage config (enabled: true, bodyPath: /etc/datum/error-pages/error-5xx.html).
  • The extension server's / coraza-envoy-go-filter's local-reply / error-page body-write logic — headers (including a correct Content-Length) appear to be sent, but the body write step seems to be skipped or the stream closed prematurely.
  • Coraza engine internal error/panic handling during the response phase that falls back to the branded error page.

Impact

Any customer with a TrafficProtectionPolicy in Enforce mode attached to a Gateway/HTTPRoute may see 100% failure (500, truncated body) on all traffic through that route, unrelated to actual WAF rule matches — this is not a false-positive block, it's every request failing. The only current workaround is to disable/detach the TPP.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions