Matched signals
- container name.*already in use
- container.*already exists
- port.*already in use
- network.*already exists
- volume.*already exists
- address already in use
- EADDRINUSE
- resource.*already allocated
Orphaned CI resources blocking subsequent runs
What this failure means
A CI job failed because a previous run left behind a container, network, volume, or bound port that was not cleaned up. The current run cannot create or start the same resource because it already exists.
Symptoms
Faultline looks for one or more of these log fragments:
container name.*already in use
container.*already exists
port.*already in use
network.*already exists
volume.*already exists
address already in use
EADDRINUSE
resource.*already allocated
Diagnosis
Orphaned resources appear when:
- A previous CI run was cancelled or crashed before its teardown step
- Docker Compose services were not stopped after a test run
- A service container keeps its name between retried jobs on the same runner
- The runner reuses workspace state without a clean slate
Inspect the runner for leftover resources:
# Containers
docker ps -a | grep <project-prefix>
docker ps -a --filter "name=<service-name>"
# Networks
docker network ls
# Volumes
docker volume ls
# Ports
ss -tlnp | grep <port>
lsof -i :<port>
Fix steps
-
Add a cleanup step at the start of the job to remove any stale resources:
# At job start — remove stale containers docker rm -f myservice 2>/dev/null || true docker network rm mynetwork 2>/dev/null || true -
For Docker Compose, use
--remove-orphansand clean up volumes:# Teardown docker compose down --remove-orphans --volumes # Pre-run cleanup docker compose rm -f -
Add a cleanup step as an
always()/ post-job hook so it runs even on failure:# GitHub Actions - name: Cleanup if: always() run: docker compose down --remove-orphans --volumes -
Use unique resource names per run to avoid collisions on shared runners:
env: SERVICE_NAME: myservice-${{ github.run_id }} -
For port conflicts, run services on dynamic ports (port 0) and discover the assigned port rather than using a fixed port number.
-
For persistent runners (self-hosted), schedule a periodic cleanup job:
# prune stopped containers, unused networks, dangling volumes docker system prune -f
Validation
- Run
docker ps -aon the runner and confirm no stale containers exist. - Re-run the failing job and confirm it starts cleanly.
Why it matters
Orphaned resources are a self-reinforcing failure: each failed run leaves more resources behind, causing subsequent runs to also fail. Without a cleanup step, the problem escalates until the runner is manually reset.
Prevention
- Always add an
if: always()cleanup step after Docker or service container usage. - Use
docker compose down --volumesrather than just stopping services. - Prefer ephemeral runners that start from a clean state on every job.
- Use run-unique resource names when cleanup is unreliable.
How Faultline detects it
Use faultline explain orphaned-resources to see the full playbook.
faultline analyze build.log
faultline explain orphaned-resources
Generated from playbooks/bundled/log/ci/orphaned-resources.yaml. Do not edit directly.