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

Open
#2,841 1 comment 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.