horsley opened a new issue, #13325:
URL: https://github.com/apache/apisix/issues/13325
### Current Behavior
Since APISIX 3.16.0, any `stream_route` that uses an xRPC protocol (e.g.
`protocol.name: redis`, `dubbo`, or a custom protocol) emits the following
error on every worker startup / config reload **in the HTTP subsystem**:
```
[error] *N [lua] config_yaml.lua:333: failed to check item data of
[stream_routes] err:unknown protocol [<name>] ,val: {...}, context:
init_worker_by_lua*
```
The same `stream_routes` entry is accepted by the Stream subsystem (where
`xrpc.check_schema` succeeds), so the tunnel still functions at runtime — but
the HTTP worker's view of `/stream_routes` silently drops the route, and any
logic that relies on the HTTP side (for example the Control API healthcheck
endpoint added in #12996, or user tests that assert `no [error]` in
`error.log`) is broken.
### Root Cause
#12996 ("feat: allow fetching stream healthcheck data through control api",
commit `2500db7a`, merged 2026-02-13) changed
`apisix/router.lua::http_init_worker` so that, whenever `apisix.stream_proxy`
is configured, the HTTP worker also initializes the stream router:
https://github.com/apache/apisix/blob/3.16.0/apisix/router.lua#L90-L96
```lua
-- Initialize stream router in HTTP workers only if stream mode is
enabled
-- This allows the Control API (which runs in HTTP workers) to access
stream routes
if conf and conf.apisix and conf.apisix.stream_proxy then
local router_stream = require("apisix.stream.router.ip_port")
router_stream.stream_init_worker(filter)
_M.router_stream = router_stream
end
```
`stream_init_worker` registers a checker that calls
`xrpc.check_schema(prot_conf, false)` for every `stream_routes` item:
https://github.com/apache/apisix/blob/3.16.0/apisix/stream/router/ip_port.lua#L216-L224
But `apisix/stream/xrpc.lua::init` still uses the pre-3.16 guard that only
registers xRPC protocol schemas in HTTP workers when the Admin API is enabled:
https://github.com/apache/apisix/blob/3.16.0/apisix/stream/xrpc.lua#L59-L62
```lua
if is_http and not local_conf.apisix.enable_admin then
-- we need to register xRPC protocols in HTTP only when Admin API is
enabled
return
end
```
So when a deployment runs with `enable_admin: false` (e.g. the data-plane
role, or any YAML/JSON `config_provider`), the HTTP worker has
`registered_protocol_schemas = {}` and every xRPC-based stream route fails
`check_schema` → `"unknown protocol [<name>]"`.
### Expected Behavior
When APISIX 3.16+ initializes the stream router inside the HTTP worker, it
should also make sure the xRPC protocol schemas are available, so that
`check_schema` succeeds and `/stream_routes` with `protocol.name =
<xrpc-protocol>` is not dropped / error-logged.
### Error Logs
```
2026/04/30 18:40:42 [error] 57836#57836: *2 [lua] config_yaml.lua:333:
failed to check item data of [stream_routes] err:unknown protocol [redis] ,val:
{"protocol":{"name":"redis","conf":{...}},"server_port":...,"id":1}, context:
init_worker_by_lua*
```
### Steps to Reproduce
1. Install APISIX 3.16.0.
2. Use `deployment.role: data_plane` with
`deployment.role_data_plane.config_provider: yaml` (or any setup where
`apisix.enable_admin = false`), and enable `apisix.stream_proxy.tcp`.
3. Add an xRPC-based stream route to `apisix.yaml`, e.g.:
```yaml
xrpc:
protocols:
- name: redis
stream_routes:
- id: 1
server_port: 9101
protocol:
name: redis
conf:
faults: []
#END
```
4. Start APISIX. The HTTP worker logs `[error] ... failed to check item data
of [stream_routes] err:unknown protocol [redis]` on every init / reload. The
stream worker does not log this error because it registers the xRPC schemas
correctly.
The same repro reproduces on 3.16.0 with any xRPC protocol (`redis`,
`dubbo`, a custom one registered in `xrpc.protocols`).
### Suggested Fix
In `apisix/stream/xrpc.lua::init`, also register protocol schemas in the
HTTP worker when `apisix.stream_proxy` is configured (mirroring the condition
added to `router.lua` in #12996):
```lua
if is_http
and not local_conf.apisix.enable_admin
and not (local_conf.apisix and local_conf.apisix.stream_proxy)
then
return
end
```
This keeps the original optimization (don't load schema modules when they
cannot possibly be used), while ensuring the HTTP-side `stream_route_checker`
introduced by #12996 has the schemas it needs.
I'm happy to send a PR if this direction sounds right.
### Environment
- APISIX version (run `apisix version`): `3.16.0`
- Operating system (run `uname -a`): `Linux ... 6.x Ubuntu 24.04`
- OpenResty / Nginx version (run `openresty -V` or `nginx -V`):
`openresty/1.27.1.2` (APISIX runtime 1.3.2)
- etcd version, if relevant: n/a (yaml `config_provider`)
- APISIX Dashboard version: n/a
- Plugin runner version: n/a
- LuaRocks version: n/a
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]