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
-- 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
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
- Install APISIX 3.16.0.
- 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.
- Add an xRPC-based stream route to
apisix.yaml, e.g.:
xrpc:
protocols:
- name: redis
stream_routes:
- id: 1
server_port: 9101
protocol:
name: redis
conf:
faults: []
#END
- 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):
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
Current Behavior
Since APISIX 3.16.0, any
stream_routethat 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:The same
stream_routesentry is accepted by the Stream subsystem (wherexrpc.check_schemasucceeds), so the tunnel still functions at runtime — but the HTTP worker's view of/stream_routessilently 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 assertno [error]inerror.log) is broken.Root Cause
#12996 ("feat: allow fetching stream healthcheck data through control api", commit
2500db7a, merged 2026-02-13) changedapisix/router.lua::http_init_workerso that, wheneverapisix.stream_proxyis configured, the HTTP worker also initializes the stream router:https://github.com/apache/apisix/blob/3.16.0/apisix/router.lua#L90-L96
stream_init_workerregisters a checker that callsxrpc.check_schema(prot_conf, false)for everystream_routesitem:https://github.com/apache/apisix/blob/3.16.0/apisix/stream/router/ip_port.lua#L216-L224
But
apisix/stream/xrpc.lua::initstill 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
So when a deployment runs with
enable_admin: false(e.g. the data-plane role, or any YAML/JSONconfig_provider), the HTTP worker hasregistered_protocol_schemas = {}and every xRPC-based stream route failscheck_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_schemasucceeds and/stream_routeswithprotocol.name = <xrpc-protocol>is not dropped / error-logged.Error Logs
Steps to Reproduce
deployment.role: data_planewithdeployment.role_data_plane.config_provider: yaml(or any setup whereapisix.enable_admin = false), and enableapisix.stream_proxy.tcp.apisix.yaml, e.g.:[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 inxrpc.protocols).Suggested Fix
In
apisix/stream/xrpc.lua::init, also register protocol schemas in the HTTP worker whenapisix.stream_proxyis configured (mirroring the condition added torouter.luain #12996):This keeps the original optimization (don't load schema modules when they cannot possibly be used), while ensuring the HTTP-side
stream_route_checkerintroduced by #12996 has the schemas it needs.I'm happy to send a PR if this direction sounds right.
Environment
apisix version):3.16.0uname -a):Linux ... 6.x Ubuntu 24.04openresty -Vornginx -V):openresty/1.27.1.2(APISIX runtime 1.3.2)config_provider)