Docker

Docker Build Error "Failed to Solve: Process Returned a Non-Zero Code"

· by DebuggedIt

Quick answer

"Failed to solve: process returned a non-zero code" is BuildKit's generic summary confirming that some command inside a RUN instruction exited with a failure...

"Failed to solve: process returned a non-zero code" is BuildKit's generic summary confirming that some command inside a RUN instruction exited with a failure status — the actual, specific reason for that failure is always printed just above this summary line, and reading past the generic wrapper is the entire key to fixing it.

The Problem

A Docker build fails at a specific RUN step:

------
 > [4/8] RUN npm install:
0.523 npm ERR! code ERESOLVE
0.524 npm ERR! ERESOLVE unable to resolve dependency tree
------
failed to solve: process "/bin/sh -c npm install" did not complete successfully: exit code: 1

The final summary line alone doesn't tell you anything actionable — the actual useful information (in this example, the specific npm dependency resolution error) is in the output immediately above it.

Why It Happens

This generic message is BuildKit's standard way of reporting that a RUN command's underlying shell process exited with a non-zero status, which by Unix convention indicates failure — but BuildKit itself doesn't know or attempt to interpret why that specific command failed, since the actual cause is entirely dependent on what that command does. Common categories of actual underlying cause:

  • A package manager command (npm install, pip install, apt-get install) failing due to a genuine dependency conflict, a missing package, or a network issue reaching the package registry during the build
  • A build or compilation step failing due to a genuine code error, missing file, or misconfiguration in the project being built
  • A command that simply doesn't exist in the base image being used, producing a "command not found" style failure rather than the command's own logical failure
  • Insufficient resources (memory, disk space) during the build causing a command to fail partway through, particularly relevant for resource-intensive build steps like compiling large native dependencies

The Fix

Always scroll up from the generic "failed to solve" summary to find the actual command output immediately preceding it — this is where the genuinely actionable error detail lives, in every single case:

docker build -t your-app . 2>&1 | tee build.log
# then review build.log in full, or specifically search near the failure point

For dependency resolution failures (a very common category), address the actual reported conflict directly — in the npm example above, this might mean resolving a genuine version conflict in package.json, or, if appropriate for the situation, explicitly allowing the resolution to proceed with a documented flag:

RUN npm install --legacy-peer-deps

Use this kind of override deliberately and with understanding of what it actually does, rather than as a reflexive fix for any dependency error without understanding the underlying conflict — sometimes the conflict indicates a genuine incompatibility worth addressing properly rather than overriding.

For build/compilation failures, the fix is specific to whatever the actual compiler or build tool error indicates — a missing file, a syntax error, a misconfigured build script — and requires addressing that specific issue in your actual source code or build configuration, information that's only visible in the detailed output above the generic summary line.

If the failure is a "command not found" style error, confirm the base image you're using actually includes that command, or install it explicitly as part of an earlier build step:

FROM node:18-alpine
RUN apk add --no-cache python3 make g++  # if these are needed but not in the base image

Alpine-based images specifically are minimal by design and often lack tools that fuller-featured base images include by default — a build step that worked fine on a Debian-based image can fail with "command not found" after switching to a leaner Alpine base, requiring explicit installation of whatever's actually needed.

If you suspect resource constraints during the build (particularly relevant for memory-intensive native compilation steps), check Docker's own allocated build resources, particularly relevant on Docker Desktop where resource limits are explicitly configurable:

# Docker Desktop > Settings > Resources > increase Memory allocation if constrained

Still Not Working?

If the detailed output above the generic summary still isn't clear enough to diagnose, run the failing command interactively inside a container based on the same image, up to the point right before the failing step, letting you manually execute and iterate on the exact command in a live, interactive shell rather than only seeing its output in a non-interactive build log:

# Build up to the layer just before the failing step
docker build --target <previous-stage-name> -t debug-image .
docker run -it debug-image sh
# then manually run the failing command and interact with the environment directly

This interactive approach is often significantly faster for genuinely puzzling build failures than repeatedly modifying the Dockerfile and re-running the full build to test each hypothesis, since you can directly explore the actual build environment's state and experiment with fixes in real time.