cross-rs/cross · error · eyre::ErrReport
container already exited due to signal
Error message
container already exited due to signal
What it means
The `bail_container_exited!` macro aborts a pending container command when the managed child container has already terminated (e.g. killed by a signal during cleanup). It only bails if `ChildContainer::exists_static()` reports the container no longer exists, preventing commands against a dead container/volume.
Solutions
- Re-run the cross command; the stale container state is cleaned up on the next invocation.
- Inspect `docker ps -a` / `docker volume ls` for orphaned cross containers/volumes and remove them.
- Avoid sending signals mid-build, or handle graceful shutdown so cleanup completes before exit.
Defensive patterns
Strategy: try-catch
Validate before calling
if !ChildContainer::exists_static() {
// container gone: skip the command and re-run from a clean state
} Try / catch
match run_in_container(...) {
Err(e) if e.to_string().contains("container already exited") => {
eprintln!("container exited early; cleaning up and retrying");
cleanup();
}
Err(e) => return Err(e),
Ok(v) => v,
} Prevention
- Avoid Ctrl-C/SIGTERM mid-build; let cleanup complete.
- Increase CI timeouts so builds aren't killed mid-operation.
- Periodically prune orphaned cross containers and volumes.
When it happens
Trigger: Executing a docker subcommand against a cross-managed container after the container process received a signal (SIGINT/SIGTERM) or exited during volume cleanup — detected via the `exists_static` check failing.
Common situations: Pressing Ctrl-C while a cross build runs in Docker, CI timeout signals killing the container, or the container crashing mid-operation and subsequent commands racing against its cleanup.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Refusing to push without tag or branch. Specify a…
- unexpected progress type: expected plain, auto, or tty and…
- cannot make definite Image from unqualified PossibleImage
- invalid platform specified
- unsupported os in target, abi
AI-assisted analysis of cross-rs/cross@8c1a8aa4b6 (2026-09-13).
Data as JSON: /api/errors/969d0287d31bfa63.
Report an issue: GitHub.
Appendix: source
Thrown at src/docker/remote.rs:29
use super::engine::Engine;
use super::shared::*;
use crate::TargetTriple;
use crate::config::bool_from_envvar;
use crate::errors::Result;
use crate::extensions::CommandExt;
use crate::file::{self, PathExt, ToUtf8};
use crate::rustc::{self, QualifiedToolchain, VersionMetaExt};
use crate::shell::MessageInfo;
use crate::temp;
// prevent further commands from running if we handled
// a signal earlier, and the volume is exited.
// this isn't required, but avoids unnecessary
// commands while the container is cleaning up.
macro_rules! bail_container_exited {
() => {{
if !ChildContainer::exists_static() {
eyre::bail!("container already exited due to signal");
}
}};
}
#[track_caller]
fn subcommand_or_exit(engine: &Engine, cmd: &str) -> Result<Command> {
bail_container_exited!();
Ok(engine.subcommand(cmd))
}
pub fn posix_parent(path: &str) -> Option<&str> {
Path::new(path).parent()?.to_str()
}
impl ContainerDataVolume<'_, '_, '_> {
// NOTE: `reldir` should be a relative POSIX path to the root directory
// on windows, this should be something like `mnt/c`. that is, all paths
// inside the container should not have the mount prefix.View on GitHub (pinned to 8c1a8aa4b6)