nautechsystems/nautilus_trader · error · anyhow::Error
Binance Spot SBE market-data streams require an Ed25519 API
Error message
Binance Spot SBE market-data streams require an Ed25519 API key (HMAC keys are not supported): {e} What it means
The Binance Spot SBE market-data WebSocket client was constructed without Ed25519-compatible credentials. SBE streams require an Ed25519 API key; an HMAC (secret-key) credential or otherwise malformed key material caused `Ed25519Credential::new` to fail, and the underlying error is surfaced via `{e}`.
Source
Thrown at crates/adapters/binance/src/spot/websocket/streams/client.rs:143
/// # Errors
///
/// Returns an error if credential creation fails.
pub fn new(
url: Option<String>,
api_key: Option<String>,
api_secret: Option<String>,
heartbeat: Option<u64>,
transport_backend: TransportBackend,
) -> anyhow::Result<Self> {
let url = url.unwrap_or(BINANCE_SPOT_SBE_WS_URL.to_string());
let credential = match (
api_key.map(SecretString::from),
api_secret.map(SecretString::from),
) {
(Some(key), Some(secret)) => {
let credential = Ed25519Credential::new(key, secret).map_err(|e| {
anyhow::anyhow!(
"Binance Spot SBE market-data streams require an Ed25519 API key \
(HMAC keys are not supported): {e}"
)
})?;
Some(Arc::new(credential))
}
_ => None,
};
Ok(Self {
url,
credential,
heartbeat,
signal: Arc::new(AtomicBool::new(false)),
slots: Arc::new(ConnectionSlots(Mutex::new(Vec::new()))),
connect_lock: Arc::new(tokio::sync::Mutex::new(())),
out_tx: Arc::new(Mutex::new(None)),
out_rx: Arc::new(Mutex::new(None)),View on GitHub (pinned to 18893faf8b)
Solutions
- Create an Ed25519-type API key on Binance (in the API management page choose Ed25519, not HMAC) and supply its public key as the api key and its private key as the secret.
- Verify the private key is a valid PEM/base64 Ed25519 key with no trailing whitespace or newlines.
- Check the underlying `{e}` message; if it says the key format is invalid, re-encode the key (e.g. ensure PEM headers/footers).
- If you cannot use Ed25519 keys, use the non-SBE (JSON) market-data streams, which accept HMAC keys.
Example fix
// before: HMAC key api_key = "my_hmac_key"; api_secret = "my_hmac_secret"; // after: Ed25519 key created on Binance api_key = "<ed25519 public key (base64)>"; api_secret = "<ed25519 private key (PEM)>";
Defensive patterns
Strategy: validation
Validate before calling
fn require_ed25519_key(api_key: &str, api_secret: &str) -> Result<(), String> {
if api_key.is_empty() || api_secret.is_empty() {
return Err("api key/secret must not be empty".into());
}
// Ed25519 private keys are PEM or base64 DER, not HMAC hex secrets
if api_secret.chars().all(|c| c.is_ascii_hexdigit()) {
return Err("secret looks like an HMAC key; SBE streams require an Ed25519 key".into());
}
Ok(())
} Try / catch
match Ed25519Credential::new(key, secret) {
Ok(c) => Ok(Some(Arc::new(c))),
Err(e) => Err(anyhow::anyhow!(
"Binance Spot SBE market-data streams require an Ed25519 API key (HMAC keys are not supported): {e}"
)),
} Prevention
- Create Ed25519-type API keys on Binance for SBE market data; never reuse HMAC keys.
- Store keys without trailing whitespace/newlines.
- Validate credential type at startup, before opening streams.
When it happens
Trigger: Calling `client.new(...)` on the Spot SBE stream client with an HMAC-style API key/secret pair, an empty key, or invalid key material; `Ed25519Credential::new(key, secret)` returns `Err`.
Common situations: Users reusing their classic HMAC Binance API key with the newer SBE endpoint; keys created without Ed25519 signing enabled; a typo'd or truncated key pasted into config.
Related errors
- Authentication failed: {e}
- WS session authentication timed out
- WS submit order failed: {e}
- WS cancel order failed: {e}
- Binance Futures shutdown failed: {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d72964e7d12e9425.
Report an issue: GitHub.