nautechsystems/nautilus_trader · error
Payload deployment or retired keys require an active payload
Error message
Payload deployment or retired keys require an active payload sealing key
What it means
PayloadSealingKeys::load returns Ok(None) (no sealing) only when there is no active key env AND no retired keys AND no deployment ID. If an active key env name is absent but retired key envs or a deployment_id are supplied, the configuration is inconsistent and this error is thrown — sealing features are configured without the required active key.
Source
Thrown at crates/adapters/blockchain/src/execution/sealing.rs:86
impl Debug for PayloadKeySet {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct(stringify!(PayloadKeySet))
.field("active_id", &hex::encode(self.active_id))
.field("key_count", &self.keys.len())
.field("deployment_id", &self.deployment_id)
.finish()
}
}
impl PayloadKeySet {
pub(crate) fn load(
active_env: Option<&str>,
retired_envs: &[String],
deployment_id: Option<&str>,
) -> anyhow::Result<Option<Self>> {
let Some(active_env) = active_env else {
anyhow::ensure!(
retired_envs.is_empty() && deployment_id.is_none(),
"Payload deployment or retired keys require an active payload sealing key"
);
return Ok(None);
};
anyhow::ensure!(
!active_env.trim().is_empty(),
"Payload key environment name is empty"
);
let deployment_id = deployment_id
.map(str::trim)
.filter(|value| !value.is_empty())
.ok_or_else(|| {
anyhow::anyhow!(
"Payload deployment ID is required when payload sealing is configured"
)
})?;
View on GitHub (pinned to 18893faf8b)
Solutions
- Set the active payload sealing key env var name in config so active_env is Some.
- Or, if sealing is intentionally disabled, remove the retired key env list and payload deployment ID from config.
- During key rotation, keep the new active key configured before moving old keys into retired_envs.
- Validate sealing config completeness at startup before calling load.
Example fix
// before retired_envs = ["PAYLOAD_KEY_OLD"] deployment_id = "dep-123" # active key env missing // after active_env = "PAYLOAD_KEY_NEW" retired_envs = ["PAYLOAD_KEY_OLD"] deployment_id = "dep-123"
Defensive patterns
Strategy: validation
Validate before calling
if active_env.is_none() && (!retired_envs.is_empty() || deployment_id.is_some()) {
panic!("sealing extras configured without an active payload sealing key env");
} Type guard
fn sealing_config_consistent(active: Option<&str>, retired: &[String], dep: Option<&str>) -> bool { active.is_some() || (retired.is_empty() && dep.is_none()) } Try / catch
match PayloadSealingKeys::load(active, &retired, dep) {
Err(e) if e.to_string().contains("require an active payload sealing key") => eprintln!("set the active key env or drop retired/deployment settings"),
other => other,
} Prevention
- During rotation, set the new active key env before marking old keys retired
- Keep the whole sealing config block enabled/disabled together
- Validate config completeness in CI before deploy
- Never comment out only the active-key line of a sealing config
When it happens
Trigger: Calling load with active_env = None while retired_envs is non-empty or deployment_id is Some — e.g. config lists retired payload key env vars or a payload deployment ID but omits the active payload sealing key env.
Common situations: Rotating keys: operator set the retired-key list/deployment ID but forgot to define the new active key env var; config template with commented-out active key line while keeping the rest; partially removed sealing config.
Related errors
- Payload deployment ID is required when payload sealing is co
- Payload key environment name is empty
- max_fee_per_contract is required
- max_fee_per_contract must be greater than zero
- Failed to create HTTP client: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/0183326433185158.
Report an issue: GitHub.