apache / apache/apisix-ingress-controller
HTTPRoute/GRPCRoute: unresolvable ExtensionRef plugin config should return a data-plane error, not skip the filter or drop the route
- Dominant language
- Go
- Stars
- 1.1k
- Forks
- 390
- Avg merge
- 3d 7h
- Merged PRs (30d)
- 12
Description
### Problem
When an `ExtensionRef` filter on an `HTTPRoute`/`GRPCRoute` points at a `PluginConfig` whose plugin `config` cannot be resolved, `fillPluginFromExtensionRef` currently skips the plugin, and the route is published without it.
Gateway API forbids that outcome. A custom filter that cannot be resolved must not be skipped; the requests that would have been processed by it must receive an HTTP error response instead:
> If a reference to a custom filter type cannot be resolved, the filter MUST NOT be skipped. Instead, requests that would have been processed by that filter MUST receive a HTTP error response.
(gateway-api v1.6.0, `apis/v1/httproute_types.go#L847-L849`)
Failing translation outright is not the fix either. It means the route is never programmed, so if another route also matches, the request is served **without** the filter — the exact outcome the spec forbids — and if nothing else matches it is a 404, indistinguishable from "no such route". It also widens a per-filter failure into a whole-route one: `TranslateHTTPRoute` aborts on the first bad filter, dropping every rule of the route, and one bad `PluginConfig` takes down every route referencing it.
### Expected behavior
Adopt the conformant pattern the translator already uses for unresolvable `backendRefs`: keep the route, and attach a `fault-injection` plugin returning 500 so the affected requests fail at the data plane rather than silently bypassing the filter. See `internal/adc/translator/httproute.go` (the `backendErr` handling and its `fault-injection` abort block), whose error is deliberately discarded at the call site precisely because it has already been turned into a data-plane 500.
Scope the failure to the rule whose filter could not be resolved, not the whole route, and set `ResolvedRefs=False` on the route so the condition is visible.
### Affected
- `internal/adc/translator/httproute.go` — `fillPluginFromExtensionRef`, `fillPluginsFromHTTPRouteFilters`
- `internal/adc/translator/grpcroute.go` — same `ExtensionRef` path
### Context
Came out of review on #2814, which makes the apiv2 plugin-config paths fail closed. The Gateway API paths were deliberately left out of that PR because they need this different, spec-conformant treatment. The apiv2 CRDs carry no such constraint.
Depends on #2840 for the failure to be observable in status at all.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with fillPluginFromExtensionRef and fillPluginsFromHTTPRouteFilters in internal/adc/translator/httproute.go, then compare the backendErr and fault-injection handling; inspect the corresponding ExtensionRef path in internal/adc/translator/grpcroute.go. The affected rule should remain published with a fault-injection response for unresolved plugin configuration, while ResolvedRefs=False is set for the route; account for the status behavior from #2840.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, kubernetes
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 54/100