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

blockedBlocked on other work before it can landbugSomething isn't working

Type

No type

Fields

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions