Troubleshooting Docker Container Exit Code 139 (Segmentation Fault) on Windows WSL2 Ubuntu
Diagnose and resolve Docker container crashes with exit code 139 (segmentation fault) running on WSL2 Ubuntu, a critical guide for developers and sysadmins.
Diagnose and resolve Docker container crashes with exit code 139 (segmentation fault) running on WSL2 Ubuntu, a critical guide for developers and sysadmins.
A Docker container exiting with code 139, often accompanied by a "segmentation fault" message, signifies a critical error where the container's main process attempted to access a memory location that it was not allowed to. This usually points to a fundamental issue within the application running inside the container or, less commonly, an underlying problem with the environment, such as resource constraints or library mismatches within your WSL2 Ubuntu setup. This guide provides a comprehensive approach to diagnosing and resolving these challenging errors.
Symptom & Error Signature
When a Docker container encounters a segmentation fault, it will abruptly terminate. You'll typically observe the following indicators:
docker ps -aoutput: The container will show anExited (139)status.root@your-wsl-ubuntu:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a1b2c3d4e5f6 my-app:latest "python app.py" 2 minutes ago Exited (139) 1 minute ago my-app-containerdocker logs <container_id>output: The logs will often explicitly state "segmentation fault" or "core dumped" just before termination.root@your-wsl-ubuntu:~# docker logs a1b2c3d4e5f6 Initializing application... Loading configuration... Segmentation fault (core dumped)Depending on the application and its logging configuration, you might see a more detailed stack trace or an application-specific crash report preceding the segmentation fault message.
Root Cause Analysis
A segmentation fault (SIGSEGV) occurs when a program tries to access a memory address outside of its allocated memory space, or tries to access it in a way that is not allowed (e.g., writing to a read-only location). In the context of Docker containers running on WSL2 Ubuntu, the underlying reasons can be multifaceted:
Application Bugs (Most Common):
- Dangling Pointers/Null Pointers: Attempting to dereference a pointer that is null or points to freed memory.
- Buffer Overflows/Underflows: Writing data beyond the boundaries of an array or buffer, corrupting adjacent memory.
- Stack Overflows: Recursive functions or excessively large local variables consuming all available stack space.
- Use-After-Free Errors: Accessing memory after it has been deallocated.
- Double-Free Errors: Attempting to deallocate the same memory twice. These are typically problems in native code (C/C++, Rust) or language runtimes with C extensions (Python, Node.js, Ruby, PHP).
Memory Corruption/Resource Exhaustion:
- While distinct from a direct OOM (Out Of Memory) error (which often results in exit code 137), severe memory pressure or incorrect memory management can sometimes lead to a segfault. If the system (WSL2 or container) runs out of available memory, the program might try to access invalid memory regions, resulting in a segfault.
- Incorrectly configured container memory limits (
-m) can starve the application.
Library Mismatch or Corruption:
- GLibC/Musl issues: If your application is built against a specific C standard library (e.g., GNU C Library – glibc) and attempts to run in a container environment using a different one (e.g., Alpine's Musl libc) without proper recompilation or linking, compatibility issues can arise.
- Incorrectly linked shared libraries: The container might be missing a required shared library or linking to an incompatible version, leading to memory access errors during runtime.
Corrupted Container Image or Host FS Issues:
- Though rare, a corrupted Docker image layer or underlying filesystem corruption on the WSL2 instance itself could potentially lead to malformed binaries or libraries that cause segfaults.
WSL2-Specific Quirks (Less Common):
- Highly optimized or low-level applications might occasionally expose subtle bugs or unusual interactions with the WSL2 kernel environment. This is less common but worth considering if all other avenues are exhausted.
Step-by-Step Resolution
Troubleshooting segmentation faults requires a systematic approach, often starting with the application itself.
1. Identify the Failing Process and Review Logs Thoroughly
Begin by using docker ps -a to confirm the container's status and docker logs to retrieve all available output.
Look for any messages before the "segmentation fault" that might indicate the last action taken by the application. This is your primary clue.
# Check all containers, find the one with Exited (139)
docker ps -a
# Get detailed logs for the identified container
docker logs <CONTAINER_ID_OR_NAME>
Pay close attention to the exact point of failure in the logs. If the crash occurs immediately on startup, it suggests an initialization issue or a fundamental problem with the application's environment or dependencies. If it happens after some runtime, it's likely triggered by a specific code path or data input.
2. Debug the Application with a Debugger (GDB)
The most effective way to pinpoint a segmentation fault in native code is by using a debugger like GDB. This requires building your application with debugging symbols and potentially adjusting container security.
Build with Debugging Symbols: Ensure your application (or the problematic library) is compiled with
-gflag for C/C++ (or equivalent for other native languages) to include debugging information.Run Container with Debugger Privileges: You need to grant the container
SYS_PTRACEcapability and disableseccomprestrictions to allow GDB to attach to and inspect processes.docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -it --rm <YOUR_IMAGE_NAME> /bin/bashReplace
<YOUR_IMAGE_NAME>with your actual image. This command starts an interactive bash shell within the container with necessary privileges.Install GDB (if not present): Inside the container, if GDB is not already installed:
apt update && apt install -y gdbRun your application under GDB: Navigate to your application's directory and run it with GDB.
gdb /path/to/your/app (gdb) runOnce the segfault occurs, GDB will break.
Get a Backtrace: At the GDB prompt, type
bt(backtrace) to see the call stack leading up to the crash. This is crucial for identifying the exact line of code or function causing the issue.(gdb) bt #0 0x0000555555555123 in problematic_function (arg=0x0) at src/main.c:42 #1 0x00005555555551a0 in another_function () at src/main.c:55 #2 0x000055555555520a in main (argc=1, argv=0x7fffffffdfc8) at src/main.c:60This output tells you the function (
problematic_function), file (src/main.c), and line number (42) where the segmentation fault occurred.
Running containers with
SYS_PTRACEandseccomp=unconfinedsignificantly lowers their security posture. Only use this for debugging purposes and never in production environments.
3. Check Container Resource Limits
Insufficient memory can sometimes lead to unexpected behavior and segmentation faults, although OOM errors are usually exit 137.
Inspect current container limits:
docker inspect <CONTAINER_ID_OR_NAME> | grep -E "Memory|Cpu"Run with explicit memory limits: Test if increasing memory resolves the issue.
docker run -m 4GB <YOUR_IMAGE_NAME>Try different values (e.g.,
-m 2GB,-m 8GB).Adjust WSL2 Memory Limits: If the host WSL2 instance itself is running low on memory, it can affect containers. Modify your
.wslconfigfile. Create or editC:Users<YourUser>.wslconfig.# C:Users<YourUser>.wslconfig [wsl2] memory=8GB # Sets the maximum memory WSL2 can use to 8GB processors=4 # Sets the number of virtual processors WSL2 can use swap=2GB # Sets the amount of swap space localhostforwarding=trueAfter modifying
.wslconfig, you must shut down WSL2 completely for changes to take effect:wsl --shutdownin PowerShell or Command Prompt. Then restart your Ubuntu instance.
4. Update Docker, WSL2, and Ubuntu
Ensure all components of your environment are up-to-date. This can fix known bugs or compatibility issues.
Update WSL2 components (from PowerShell/CMD):
wsl --update wsl --version # Verify the kernel versionUpdate Ubuntu packages (from within your WSL2 Ubuntu instance):
sudo apt update && sudo apt upgrade -y sudo apt dist-upgrade -y # For significant version changesUpdate Docker Desktop: Ensure your Docker Desktop application on Windows is running the latest stable version. Check for updates via the Docker Desktop settings or official website.
5. Verify Library Compatibility and Base Image
A common source of segfaults in containers is an incompatible library.
Check Base Image: If your
Dockerfileuses a very minimal base image (e.g.,alpine), consider temporarily switching to a more feature-rich Debian-based image (e.g.,ubuntu:latest,debian:stable). Alpine uses Musl libc, while most other distributions use GLibC, and some native binaries compiled for GLibC may fail on Musl.# Example: Switch base image FROM ubuntu:22.04 # ... rest of your DockerfileInspect Shared Libraries: Inside your running container (or a temporary one created from your image), you can use
lddto list dynamic library dependencies of your executable. This helps identify if a library is missing or unexpectedly linked.# Example for Python: docker run -it --rm <YOUR_IMAGE_NAME> /bin/bash # Inside container: ldd /usr/bin/python3.10 # Or path to your specific binaryLook for
not founderrors or unusual library paths.
6. Rebuild/Re-pull Docker Image with --no-cache
Sometimes a corrupted or stale cache can lead to issues. Forcing a full rebuild ensures all layers are fresh.
Rebuild your image:
docker build --no-cache -t <YOUR_IMAGE_NAME> .Re-pull external images: If you're using a public image, try pulling it again to ensure you have the latest and uncorrupted version.
docker pull <IMAGE_NAME>:<TAG>
Using
docker builder prune -acan delete a significant amount of cached data, potentially slowing down subsequent builds. Use with caution and only if-no-cachedoesn't resolve the issue and you suspect a deeper build cache corruption.
7. Reproduce in a Minimal Environment (Isolation)
If the segfault is elusive, try to strip down your application and its environment to the bare minimum to isolate the problem.
- Minimal
Dockerfile: Create a newDockerfilethat only installs your application's direct dependencies and runs the failing part of the code. - Minimal data: Use a very small dataset or simple input if the application processes data.
- Remove non-essential services: If your container runs multiple services (e.g., Nginx, PHP-FPM, Redis), isolate the one that's crashing.
By following these steps, you should be able to systematically diagnose and resolve the "Docker container exited with code 139 segmentation fault" error, restoring stability to your WSL2-based containerized applications.
Our Production Verification Guarantee
Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.