nautechsystems/nautilus_trader · error · TransportError
Connection rate keys require a connection rate limiter
Error message
Connection rate keys require a connection rate limiter
What it means
resolve_connection_rate_limit enforces that connection rate keys are only meaningful alongside a rate limiter: keys select which entries in the limiter are consulted. If keys are provided but rate_limiter is None, the configuration is incomplete and this InvalidInput TransportError is returned at client construction. Providing keys without a limiter would silently do nothing, so the builder rejects it instead.
Source
Thrown at crates/network/src/websocket/client.rs:2849
IncomingHandler::Epoch(epoch_handler),
ping_handler,
rate_limiter,
state_sink,
connection_rate_limit,
InitialConnectOptions {
retry_policy: initial_connect_retry_policy,
cancellation_token,
},
)
.await
}
fn resolve_connection_rate_limit(
rate_limiter: Option<Arc<RateLimiter<Ustr, MonotonicClock>>>,
keys: Arc<[Ustr]>,
) -> Result<Option<ConnectionRateLimit>, TransportError> {
if rate_limiter.is_none() && !keys.is_empty() {
return Err(TransportError::Io(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"Connection rate keys require a connection rate limiter",
)));
}
if rate_limiter.is_some() && keys.is_empty() {
return Err(TransportError::Io(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"Connection rate limiter requires at least one connection rate key",
)));
}
Ok(rate_limiter.map(|limiter| ConnectionRateLimit { limiter, keys }))
}
fn resolve_rate_limiter(
default_quota: Option<Quota>,
keyed_quotas: Vec<(String, Quota)>,View on GitHub (pinned to 18893faf8b)
Solutions
- Supply a RateLimiter instance alongside the connection_rate_keys
- If rate limiting is not wanted, clear the connection_rate_keys list
- Make your config layer construct limiter and keys together as one unit
Example fix
// before
builder.connection_rate_keys(keys) // no limiter set
// after
builder
.connection_rate_limiter(Arc::new(RateLimiter::new(clock)))
.connection_rate_keys(keys) Defensive patterns
Strategy: validation
Validate before calling
if rate_limiter.is_none() && !connection_rate_keys.is_empty() {
return Err(anyhow!("connection_rate_keys set without a rate limiter"));
} Try / catch
match WebSocketClient::new(...) {
Err(e) if e.to_string().contains("require a connection rate limiter") => {
// either supply a limiter or clear keys, then rebuild
}
r => r?,
} Prevention
- Treat limiter and keys as a single config unit; construct them together
- When disabling rate limiting for dev, clear keys too
- Validate the pair at config-load time before building the client
When it happens
Trigger: Building WebSocketClient with a non-empty connection_rate_keys Arc<[Ustr]> but no rate_limiter (Option<Arc<RateLimiter<Ustr, MonotonicClock>>> = None).
Common situations: Config layers that populate rate keys from config but construct the limiter only under a separate flag; disabling the limiter for dev environments while leaving keys set; copy-paste of key lists without the limiter setup.
Related errors
- Connection rate limiter requires at least one connection rat
- Both `api_key` and `api_secret` must be provided together
- Not a subscription channel: {kind}
- Verified action requires the configured provider identities
- {field} must be non-negative, was {value}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/251bbddf7bbe4a0b.
Report an issue: GitHub.