cross-rs/cross · warning
container was running.
Error message
container {container_id} was running. What it means
At the start of a remote run, cross reuses or cleans up a leftover container from a previous run. If the container with the expected ID is still running, it warns, stops it with the default timeout, and continues cleanup (removing it if it exists).
Solutions
- Nothing required — cross stops and cleans the container automatically; investigate only if this repeats.
- Avoid killing cross mid-build; use `crossutil`/docker CLI to clean leftover containers (`docker rm -f <container_id>`).
- Ensure no two cross remote runs execute concurrently in the same Docker context.
Example fix
# before: leftover container from interrupted run docker ps # shows cross container running # after: clean up manually if needed docker rm -f <container_id> cross build --remote --target aarch64-unknown-linux-gnu
Defensive patterns
Strategy: fallback
Validate before calling
# Detect a leftover running container before invoking cross id=$(docker ps -q --filter name=cross-) [ -n "$id" ] && docker rm -f "$id"
Try / catch
// Warning is auto-handled; retry only if cleanup itself failed
if let Err(e) = run() {
if e.to_string().contains("was running") { std::thread::sleep(STOP_GRACE); retry(); } else { return Err(e); }
} Prevention
- Let cross finish or use its own cancellation path instead of SIGKILL
- Avoid concurrent cross remote runs in one Docker context
- Prune leftover containers after CI cancellations
When it happens
Trigger: run() finds a previous remote-build container (from a crashed/interrupted run) whose state is not stopped, so container.state(msg_info)? returns running and the warn branch fires.
Common situations: A previous cross remote build was killed (Ctrl-C, CI timeout, machine reboot) leaving the container running; concurrent cross runs colliding on the same container ID.
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
- container was exited.
- attempted to create already existing container.
- source is pointing to a directory instead of its contents
- copied directory contained symlinks. if the volume the link…
- artifact path does not start with , skipping
AI-assisted analysis of cross-rs/cross@8c1a8aa4b6 (2026-09-13).
Data as JSON: /api/errors/8b0ad9bff6a2acf8.
Report an issue: GitHub.
Appendix: source
Thrown at src/docker/remote.rs:804
let existing = DockerVolume::existing(engine, toolchain_dirs.toolchain(), msg_info)?;
if existing.iter().any(|v| v == &toolchain_id) {
VolumeId::Keep(toolchain_id)
} else {
let partial = format!("{VOLUME_PREFIX}{}", toolchain_dirs.toolchain());
if existing.iter().any(|v| v.starts_with(&partial)) {
msg_info.warn(format_args!(
"a persistent volume does not exists for `{0}`, but there is a volume for a different version.\n > Create a new volume with `cross-util volumes create --toolchain {0}`",
toolchain_dirs.toolchain()
))?;
}
VolumeId::Discard
}
};
let container = DockerContainer::new(engine, &container_id);
let state = container.state(msg_info)?;
if !state.is_stopped() {
msg_info.warn(format_args!("container {container_id} was running."))?;
container.stop_default(msg_info)?;
}
if state.exists() {
msg_info.warn(format_args!("container {container_id} was exited."))?;
container.remove(msg_info)?;
}
// 2. create our volume to copy all our data over to
// we actually use an anonymous volume, so it's auto-cleaned up,
// if we're using a discarded volume.
// 3. create our start container command here
let mut docker = engine.subcommand("run");
docker.add_userns();
options
.image
.platform
.specify_platform(&options.engine, &mut docker);View on GitHub (pinned to 8c1a8aa4b6)