{"record":{"id":"78ec4feabdfe1c1f","repo":"nautechsystems/nautilus_trader","slug":"credentials-required-for-channel","errorCode":null,"errorMessage":"Credentials required for {channel}","messagePattern":"Credentials required for (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/coinbase/src/websocket/client.rs","lineNumber":393,"sourceCode":"        }) {\n            self.out_rx = None;\n            anyhow::bail!(\"Failed to start Coinbase WebSocket handler task: {e}\");\n        }\n\n        Ok(())\n    }\n\n    /// Subscribes to a channel for the given product IDs.\n    pub async fn subscribe(\n        &self,\n        channel: CoinbaseWsChannel,\n        product_ids: &[Ustr],\n    ) -> anyhow::Result<()> {\n        let jwt = if channel.requires_auth() {\n            let credential = self\n                .credential\n                .as_ref()\n                .ok_or_else(|| anyhow::anyhow!(\"Credentials required for {channel}\"))?;\n            Some(credential.build_ws_jwt()?)\n        } else {\n            self.credential.as_ref().and_then(|c| c.build_ws_jwt().ok())\n        };\n\n        let sub = protect_subscription(CoinbaseWsSubscription {\n            msg_type: CoinbaseWsAction::Subscribe,\n            product_ids: product_ids.to_vec(),\n            channel,\n            jwt,\n        })?;\n\n        let channel_str = channel.as_ref();\n\n        if product_ids.is_empty() {\n            self.subscriptions.mark_subscribe(channel_str);\n        } else {\n            for product_id in product_ids {","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/coinbase/src/websocket/client.rs#L375-L411","documentation":"The Coinbase WebSocket client requires credentials when subscribing to authenticated channels (e.g. the `user` channel). If no credential was configured on the client, `subscribe` fails fast with this error before sending anything. Optional JWTs are only attached when credentials exist and the channel requires auth.","triggerScenarios":"Calling `subscribe` for a channel whose `requires_auth()` is true (such as CoinbaseWsChannel::User) while the client was constructed without credentials.","commonSituations":"Building the websocket client without passing Coinbase API key/secret/passphrase, then subscribing to the user channel for private fills/orders; env vars for Coinbase credentials unset or mistyped.","solutions":["Provide credentials when constructing the websocket client","Subscribe only to public channels if you do not intend to authenticate","Verify Coinbase API key environment variables are set and loaded into the credential","Check that the channel you intend truly requires auth and use the correct public channel otherwise"],"exampleFix":"// before\nlet client = CoinbaseWsClient::new(None, url, rx).await?;\nclient.subscribe(CoinbaseWsChannel::User, &products).await?;\n// after\nlet credential = CoinbaseCredentials::from_env()?;\nlet client = CoinbaseWsClient::new(Some(credential), url, rx).await?;\nclient.subscribe(CoinbaseWsChannel::User, &products).await?;","handlingStrategy":"validation","validationCode":"fn can_subscribe(channel: CoinbaseWsChannel, cred: &Option<CoinbaseCredentials>) -> Result<(), String> {\n    if channel.requires_auth() && cred.is_none() {\n        return Err(format!(\"channel {channel} requires credentials\"));\n    }\n    Ok(())\n}","typeGuard":"fn require_credentials<'a>(cred: &'a Option<CoinbaseCredentials>) -> Option<&'a CoinbaseCredentials> {\n    cred.as_ref()\n}","tryCatchPattern":"if let Err(e) = client.subscribe(CoinbaseWsChannel::User, &products).await {\n    if e.to_string().starts_with(\"Credentials required\") {\n        eprintln!(\"configure Coinbase API credentials before user-channel subscribe\");\n    }\n}","preventionTips":["Load credentials from env at client construction and fail fast if auth channels are needed","Only subscribe to auth channels (user) after verifying credentials exist","Document which Coinbase channels require authentication in your config schema"],"tags":["coinbase","websocket","authentication"],"backgroundTag":"missing-credentials","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}