{"record":{"id":"9f6a73b1474ddd03","repo":"nautechsystems/nautilus_trader","slug":"api-credentials-not-configured","errorCode":null,"errorMessage":"API credentials not configured","messagePattern":"API credentials not configured","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"crates/adapters/architect_ax/src/factories.rs","lineNumber":105,"sourceCode":"        _cache: CacheView,\n        _clock: Rc<RefCell<dyn Clock>>,\n    ) -> anyhow::Result<Box<dyn DataClient>> {\n        let ax_config = config\n            .as_any()\n            .downcast_ref::<AxDataClientConfig>()\n            .ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"Invalid config type for AxDataClientFactory. Expected AxDataClientConfig, was {config:?}\",\n                )\n            })?\n            .clone();\n\n        let client_id = ClientId::from(name);\n\n        let http_client = if ax_config.has_api_credentials() {\n            let credential =\n                Credential::resolve(ax_config.api_key.clone(), ax_config.api_secret.clone())\n                    .ok_or_else(|| anyhow::anyhow!(\"API credentials not configured\"))?;\n\n            AxHttpClient::with_credentials(\n                credential.api_key().to_string(),\n                credential.api_secret().to_string(),\n                Some(ax_config.http_base_url()),\n                None, // orders_base_url\n                ax_config.http_timeout_secs,\n                ax_config.max_retries,\n                ax_config.retry_delay_initial_ms,\n                ax_config.retry_delay_max_ms,\n                ax_config.proxy_url.clone(),\n            )\n            .map_err(|e| anyhow::anyhow!(\"Failed to create HTTP client: {e}\"))?\n        } else {\n            AxHttpClient::new(\n                Some(ax_config.http_base_url()),\n                None, // orders_base_url\n                ax_config.http_timeout_secs,","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/architect_ax/src/factories.rs#L87-L123","documentation":"In the data-client factory, has_api_credentials() said a credential pair was available (key from config or AX_API_KEY, secret from config or AX_API_SECRET), but Credential::resolve then returned None - meaning a complete pair could not actually be assembled from the provided values plus environment. The classic cause is a half-configured pair: one component supplied in config or env and the other missing or empty, in a combination where the fallback rules cannot complete both sides.","triggerScenarios":"Setting api_key in config but neither api_secret in config nor AX_API_SECRET in the environment (or vice versa); exporting only one of AX_API_KEY/AX_API_SECRET; empty-string values that count as 'set' for one check but fail resolution; env vars removed between the two checks.","commonSituations":"Docker/systemd units where only one secret env var was added; CI pipelines masking one var; .env files with a typo'd variable name (AX_API_SECREY).","solutions":["Provide BOTH api_key and api_secret in the AxDataClientConfig, or export BOTH AX_API_KEY and AX_API_SECRET","Print env::var(\"AX_API_KEY\").is_ok() and env::var(\"AX_API_SECRET\").is_ok() right before node build to confirm the pair","Watch for empty strings: an exported-but-empty var is not a usable credential","Keep credentials in both places identical (config overrides env) to eliminate mixed sources"],"exampleFix":"# before\nexport AX_API_KEY=...\n# AX_API_SECRET never set -> \"API credentials not configured\"\n# after\nexport AX_API_KEY=...\nexport AX_API_SECRET=...\n# or in config\nlet cfg = AxDataClientConfig::builder()\n    .api_key(Some(key))\n    .api_secret(Some(secret))\n    .build()?;","handlingStrategy":"validation","validationCode":"// Assert a complete pair exists before building the node\nlet (k, s) = (\n    std::env::var(\"AX_API_KEY\").ok().or(config.api_key.clone()),\n    std::env::var(\"AX_API_SECRET\").ok().or(config.api_secret.clone()),\n);\nensure!(k.as_deref().map_or(false, |v| !v.is_empty()), \"AX_API_KEY missing/empty\");\nensure!(s.as_deref().map_or(false, |v| !v.is_empty()), \"AX_API_SECRET missing/empty\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set both vars in one place (a sourcing script or secret manager) so they cannot diverge","Fail fast at process start with an explicit env check rather than deep inside factory creation","In containers, use secrets files or injected env pairs, never partial manual exports"],"tags":["architect-ax","credentials","env-vars","config","rust"],"backgroundTag":"missing-env-var","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}