## TL;DR
Exit code 125 means the Docker daemon itself failed to start or create the container, so your image's entrypoint never ran. Read the daemon-side error in the step log; it is usually a bad flag, a missing image, or a volume or port conflict.

```text
docker: Error response from daemon: [REASON].
# step exits with code 125
```

## Steps

1. Read the full daemon error message in the step log, not just the exit code:
```bash
gh run view [RUN_ID] --log | grep -B2 -A8 "exit code 125\|Error response from daemon" | head -40
```
Expected: the daemon's own reason, such as a missing image, a port already allocated, or an invalid mount.

2. If the error is a missing image, verify the name and tag resolve:
```bash
docker pull [IMAGE]:[TAG]
```
Expected: the image pulls. If it fails here, the workflow references a tag that does not exist or a registry the runner cannot reach.

3. If the error is a port conflict, find what already holds the port:
```bash
docker ps --format '{{.Names}} {{.Ports}}' | grep [PORT]
```
Expected: the container squatting on the port. Stop it or map a different host port in the workflow.

4. If the error is an invalid mount, check the host path exists on the runner:
```bash
ls -ld [HOST_PATH]
```
Expected: the path exists and is a directory if you mount it as one. Mounting a missing host path is a classic 125.

5. Rerun the workflow after the fix:
```bash
gh run rerun [RUN_ID]
```
Expected: the docker step starts the container and your entrypoint runs.

## When to use
- A docker run step fails with exit code 125 and an Error response from daemon line
- The container never starts, so there are no application logs to read
- Service containers in the workflow fail during setup

## When not to use
- The container starts and your app exits nonzero; that is exit code 1 or your app's own code, not 125
- The failure is `docker: command not found`; the CLI is missing, not the daemon
- Builds fail; those are build errors with their own codes

## Why it happens
Docker reserves exit code 125 for failures in the daemon's own operation: resolving the image, creating the container config, allocating ports and volumes. Application failures inside a running container surface as the application's own exit code. So 125 always means the problem is in how the container was requested, never in what it would have run.

## Edge cases
- On GitHub-hosted runners, leftover containers from a previous failed job can hold ports; the runner is fresh each job, so suspect your own workflow's earlier steps instead
- `--gpus` or device flags on a runner without those devices produce 125 with a terse daemon error
- Image names without an explicit tag default to latest, which may not exist; always pin the tag
- Daemon storage driver issues after disk pressure produce 125s across all docker steps; check runner disk before chasing flags

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_jTXPgZlEU7uQuhJHruzKig
