nautechsystems/nautilus_trader · error · anyhow::Error

Container ID missing

Error message

Container ID missing

What it means

container_status inspects the gateway container's state via the Docker API and, when the container reports 'running', reads its container.id to check login status. The bollard API models id as optional; if Docker returns a running container without an id, this error is raised because login checks and subsequent management require the id. This is an unexpected Docker API response rather than a gateway misconfiguration.

Source

Thrown at crates/adapters/interactive_brokers/src/gateway/dockerized.rs:305

                .unwrap_or(false)
        });

        let Some(container) = container else {
            return Ok(ContainerStatus::NoContainer);
        };

        let state = container
            .state
            .as_ref()
            .map(|state| state.as_ref())
            .unwrap_or("unknown");

        match state {
            "running" => {
                let container_id = container
                    .id
                    .as_ref()
                    .ok_or_else(|| anyhow::anyhow!("Container ID missing"))?;

                if self.is_logged_in(container_id).await.unwrap_or(false) {
                    Ok(ContainerStatus::Ready)
                } else {
                    Ok(ContainerStatus::ContainerStarting)
                }
            }
            "stopped" | "exited" => Ok(ContainerStatus::ContainerStopped),
            "created" => Ok(ContainerStatus::ContainerCreated),
            _ => Ok(ContainerStatus::Unknown),
        }
    }

    /// Start the gateway container.
    ///
    /// # Arguments
    ///
    /// * `wait` - Optional wait time in seconds (overrides config timeout)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Retry container_status after a short delay — the id is usually present on the next poll.
  2. Verify Docker daemon health and version; upgrade an outdated daemon if ids are being omitted.
  3. Recreate the gateway container (stop/remove then start) if the container record is corrupted.
  4. Check whether any Docker socket proxy/middleware strips fields from inspect/list responses.

Example fix

// defensive caller pattern
match gateway.container_status().await {
    Ok(status) => use(status),
    Err(e) if e.to_string().contains("Container ID missing") => {
        tokio::time::sleep(Duration::from_secs(2)).await; // retry transient Docker race
        retry_or_recreate_container();
    }
    Err(e) => return Err(e),
}
Defensive patterns

Strategy: retry

Validate before calling

let container = containers.first().ok_or("no gateway container")?;
if container.state.as_deref() == Some("running") && container.id.is_none() {
    // transient incomplete response — skip this poll and retry
}

Type guard

fn has_id(container: &Container) -> bool {
    container.id.is_some()
}

Try / catch

for attempt in 0..3 {
    match gateway.container_status().await {
        Ok(status) => break status,
        Err(e) if e.to_string().contains("Container ID missing") && attempt < 2 => {
            tokio::time::sleep(Duration::from_secs(2)).await;
        }
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: Calling container_status (directly or via start) when the Docker API returns a container in 'running' state whose `id` field is None — typically a transient/inconsistent Docker daemon response or an API/serialization quirk.

Common situations: Race during rapid start/stop cycles where the daemon's inspect data is momentarily incomplete; older Docker daemon versions or socket proxying that drop fields; listing by filter that returns a stale/partial container struct.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/124d81328240c7f0. Report an issue: GitHub.