nautechsystems/nautilus_trader · error
API key must be provided or set in the 'TARDIS_API_KEY' envi
Error message
API key must be provided or set in the 'TARDIS_API_KEY' environment variable
What it means
The Tardis HTTP client requires an API key for authentication (Tardis API is key-gated). Credential::resolve checks the explicit `api_key` argument and then the TARDIS_API_KEY environment variable; if neither yields a credential, the client refuses to construct.
Source
Thrown at crates/adapters/tardis/src/http/client.rs:92
impl TardisHttpClient {
/// Creates a new [`TardisHttpClient`] instance.
///
/// # Errors
///
/// Returns an error if no API key is provided (argument or `TARDIS_API_KEY` env var),
/// or if the HTTP client cannot be built.
pub fn new(
api_key: Option<&str>,
base_url: Option<&str>,
timeout_secs: Option<u64>,
normalize_symbols: bool,
proxy_url: Option<String>,
) -> anyhow::Result<Self> {
let credential = Credential::resolve(api_key.map(ToString::to_string));
if credential.is_none() {
anyhow::bail!(
"API key must be provided or set in the 'TARDIS_API_KEY' environment variable"
);
}
let base_url =
base_url.map_or_else(|| TARDIS_HTTP_BASE_URL.to_string(), ToString::to_string);
let mut headers = HashMap::new();
headers.insert(USER_AGENT.to_string(), NAUTILUS_USER_AGENT.to_string());
if let Some(ref cred) = credential {
headers.insert(
"Authorization".to_string(),
format!("Bearer {}", cred.api_key()),
);
}
let keyed_quotas = vec![(TARDIS_REST_RATE_KEY.to_string(), *TARDIS_REST_QUOTA)];View on GitHub (pinned to 18893faf8b)
Solutions
- Set the environment variable: export TARDIS_API_KEY="your-key"
- Pass the key explicitly to the constructor: api_key = Some("your-key")
- In CI/deployment, inject the secret into the environment (e.g. GitHub Actions secrets, docker -e)
- Check for typos in the env var name and that the process actually inherits it (printenv TARDIS_API_KEY)
Example fix
// before
let client = TardisHttpClient::new(None, None, None, None)?; // no key anywhere
// after
let client = TardisHttpClient::new(Some("td-xxxx"), None, None, None)?;
// or: export TARDIS_API_KEY="td-xxxx" then TardisHttpClient::new(None, ...) Defensive patterns
Strategy: validation
Validate before calling
fn ensure_tardis_key(api_key: Option<&str>) -> Result<(), String> {
let resolved = api_key
.map(str::trim)
.filter(|k| !k.is_empty())
.map(String::from)
.or_else(|| std::env::var("TARDIS_API_KEY").ok());
match resolved {
Some(_) => Ok(()),
None => Err("Set TARDIS_API_KEY or pass api_key".into()),
}
} Try / catch
let client = TardisHttpClient::new(api_key, None, None, None)
.map_err(|e| {
if e.to_string().contains("API key must be provided") {
anyhow::anyhow!("TARDIS_API_KEY missing: export it or pass api_key explicitly")
} else { e }
})?; Prevention
- Export TARDIS_API_KEY in shell profiles and container images
- Verify with `printenv TARDIS_API_KEY` in the exact runtime environment
- Inject secrets in CI rather than relying on local env
When it happens
Trigger: Calling the Tardis HTTP client constructor (new) with None/empty api_key while the TARDIS_API_KEY environment variable is unset in the process environment.
Common situations: Forgot to export TARDIS_API_KEY in the shell or container; key set in a different environment (IDE vs terminal vs systemd); key passed with surrounding whitespace or as an empty string; running in CI where the secret wasn't injected.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
- Authentication failed: {e}
- Binance Spot SBE market-data streams require an Ed25519 API
- Missing credentials
- Binance Spot market data mode SBE requires Ed25519 API crede
- Missing API credentials; set Deribit environment variables
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/10999fcbb3f8049e.
Report an issue: GitHub.