Summary
After upgrading to celestia-node v0.31.3, websocket-based subscriptions started failing with websocket: bad handshake and clients fall back to polling.
Environment
- Version:
v0.31.3
- Network: observed on Mocha
- Deployment: celestia-nodes behind a TCP load balancer
- The same load balancer setup worked before upgrading
[RPC.RateLimit] Enabled = false
Relevant config:
[RPC]
Address = "localhost"
Port = "36659"
SkipAuth = false
TLSEnabled = false
[RPC.RateLimit]
Enabled = false
RequestsPerSec = 100
Burst = 200
CacheSize = 8192
Errors
WRN DA websocket connection failed, falling back to DA polling error="failed to connect to header namespace: cannot dial address <ws://REDACTED:36668> for websocket: bad handshake: websocket: bad handshake" component=main
A related subscription error was also observed:
DA subscription failed, reconnecting error="subscribe namespace 0: blob subscribe: RPC error (-32601): method 'blob.Subscribe' not supported in this mode (no out channel support)" component=syncer
Suspected area
v0.31.3 includes RPC hardening from #4909, including an always-on maxConcurrentConns = 500 middleware around the RPC handler.
Because websocket upgrades hold the handler open for the lifetime of the websocket connection, this limit may effectively cap active websocket subscriptions. If saturated, new websocket upgrade requests could receive an HTTP rejection and surface client-side as websocket: bad handshake.
The optional per-IP rate limiter is disabled in this setup, so this does not appear to be the [RPC.RateLimit] path.
Questions
- Are websocket subscriptions expected to remain supported in
v0.31.3?
- Can the always-on
maxConcurrentConns = 500 reject websocket upgrades under load?
- Should websocket connections have a separate configurable limit from normal HTTP RPC requests?
- Should
maxConcurrentConns be operator-configurable?
- Can failed websocket upgrades log or expose the HTTP status/reason?
Expected behavior
Websocket subscriptions should continue to work after upgrading to v0.31.3, or any new limit affecting websocket subscriptions should be documented and configurable.
Actual behavior
Websocket handshakes fail with websocket: bad handshake, and clients fall back to polling.
Summary
After upgrading to
celestia-node v0.31.3, websocket-based subscriptions started failing withwebsocket: bad handshakeand clients fall back to polling.Environment
v0.31.3[RPC.RateLimit] Enabled = falseRelevant config:
Errors
A related subscription error was also observed:
Suspected area
v0.31.3includes RPC hardening from #4909, including an always-onmaxConcurrentConns = 500middleware around the RPC handler.Because websocket upgrades hold the handler open for the lifetime of the websocket connection, this limit may effectively cap active websocket subscriptions. If saturated, new websocket upgrade requests could receive an HTTP rejection and surface client-side as
websocket: bad handshake.The optional per-IP rate limiter is disabled in this setup, so this does not appear to be the
[RPC.RateLimit]path.Questions
v0.31.3?maxConcurrentConns = 500reject websocket upgrades under load?maxConcurrentConnsbe operator-configurable?Expected behavior
Websocket subscriptions should continue to work after upgrading to
v0.31.3, or any new limit affecting websocket subscriptions should be documented and configurable.Actual behavior
Websocket handshakes fail with
websocket: bad handshake, and clients fall back to polling.