nautechsystems/nautilus_trader · error · TransportError
Cannot configure both ping_handler and epoch_ping_handler
Error message
Cannot configure both ping_handler and epoch_ping_handler
What it means
The WebSocketClient builder accepts two mutually exclusive incoming-ping mechanisms: a plain ping_handler and an epoch_ping_handler (which receives the connection epoch). Supplying both is an invalid configuration, rejected at build time with this InvalidInput TransportError before any connection is made. The client cannot represent both handler styles simultaneously, so the configuration is refused early.
Source
Thrown at crates/network/src/websocket/client.rs:2817
finish_fn = connect
)]
pub async fn epoch_builder(
config: WebSocketConfig,
epoch_handler: EpochMessageHandler,
ping_handler: Option<PingHandler>,
epoch_ping_handler: Option<EpochPingHandler>,
#[builder(default)] keyed_quotas: Vec<(String, Quota)>,
default_quota: Option<Quota>,
rate_limiter: Option<Arc<RateLimiter<Ustr, MonotonicClock>>>,
state_sink: Option<SocketStateSink>,
connection_rate_limiter: Option<Arc<RateLimiter<Ustr, MonotonicClock>>>,
#[builder(default)] connection_rate_keys: Arc<[Ustr]>,
initial_connect_retry_policy: Option<InitialConnectRetryPolicy>,
cancellation_token: Option<CancellationToken>,
) -> Result<Self, TransportError> {
let ping_handler = match (ping_handler, epoch_ping_handler) {
(Some(_), Some(_)) => {
return Err(TransportError::Io(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"Cannot configure both ping_handler and epoch_ping_handler",
)));
}
(Some(handler), None) => Some(IncomingPingHandler::Ping(handler)),
(None, Some(handler)) => Some(IncomingPingHandler::Epoch(handler)),
(None, None) => None,
};
let rate_limiter = Self::resolve_rate_limiter(default_quota, keyed_quotas, rate_limiter)?;
let connection_rate_limit =
Self::resolve_connection_rate_limit(connection_rate_limiter, connection_rate_keys)?;
Self::connect_with_handler_scoped(
config,
IncomingHandler::Epoch(epoch_handler),
ping_handler,
rate_limiter,
state_sink,
connection_rate_limit,View on GitHub (pinned to 18893faf8b)
Solutions
- Remove the legacy ping_handler and keep only epoch_ping_handler if you need epoch context
- Keep only ping_handler if epoch tracking is unnecessary
- Centralize handler selection in one config path so only one is ever populated
- At your config layer, treat the two fields as mutually exclusive and error early with a clear message
Example fix
// before WebSocketClient::new(..., Some(ping_handler), Some(epoch_ping_handler), ...)? // after WebSocketClient::new(..., None, Some(epoch_ping_handler), ...)?
Defensive patterns
Strategy: validation
Validate before calling
if ping_handler.is_some() && epoch_ping_handler.is_some() {
return Err(anyhow!("only one of ping_handler / epoch_ping_handler may be set"));
} Try / catch
match WebSocketClient::new(..., ping_handler, epoch_ping_handler, ...) {
Err(e) if e.to_string().contains("both ping_handler") => {
// fix config: drop the legacy handler and retry construction
}
r => r?,
} Prevention
- During migration to epoch_ping_handler, delete the legacy handler rather than keeping both
- Model the two options as a single enum in your own config layer
- Add a config-load-time assertion that at most one is set
When it happens
Trigger: Calling WebSocketClient::new (builder) with Some(...) for both ping_handler and epoch_ping_handler parameters.
Common situations: Migrating code from the legacy ping_handler to epoch_ping_handler but leaving both set in config; a shared config layer that populates both from different sources; copy-paste wiring that forwards the existing handler plus a new epoch-aware one.
Related errors
- Both `api_key` and `api_secret` must be provided together
- Connection rate keys require a connection rate limiter
- Connection rate limiter requires at least one connection rat
- subscription state lock poisoned
- Unsupported blockchain {blockchain} for RPC connection
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5abacdac8631714d.
Report an issue: GitHub.