Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AI for Automation By James Joyner IV · · 8 min read Last reviewed Jul 2026

Make Error: '*** [Makefile:42: build] Error 1' — Cause, Fix, and Troubleshooting Guide

Quick answer

Fix make *** [Makefile:42: build] Error 1 — a recipe command exited non-zero and make aborted. The real error is on the lines above; how to find and fix it.

  • #automation
  • #troubleshooting
  • #make
Free toolkit

Fixing errors like this? Get 500 free DevOps AI prompts

500 copy-paste AI prompts for the stack you actually run — one PDF, free.

Overview

make: *** [Makefile:42: build] Error 1 means make ran a recipe command for the build target, that command exited with status 1, and make aborted the build. The Makefile:42 is the line in the Makefile where the failing recipe lives; build is the target; Error 1 is the exit status the command returned.

This line is make reporting a failure, not the failure itself. The actual error — the compiler message, the failing test, the command not found — is printed above this line by the command that failed. Make just adds this summary and stops so it does not build on top of broken output. New users often paste this last line looking for help; the useful information is in the lines they scrolled past.

A typical failure looks like this, with the real cause immediately above make’s summary:

$ make build
gcc -c -o app.o app.c
app.c:12:5: error: 'retval' undeclared (first use in this function)
   12 |     retval = do_work();
      |     ^~~~~~
make: *** [Makefile:42: build] Error 1

Here Error 1 is gcc’s exit status; the compiler error two lines up is what you fix.

Symptoms

  • make: *** [Makefile:<line>: <target>] Error <N> and the build stops.
  • One or more error lines appear immediately above from the tool make invoked (compiler, linker, test runner, shell).
  • Error 2, Error 127 (command not found), Error 126 (permission), or other non-zero statuses depending on what failed.
  • The build worked on another machine or last week — a tool, dependency, or file changed.
  • With make -k, make keeps going and prints several Error N lines for independent targets.

Common Root Causes

1. The invoked command genuinely failed

A compile error, a failed test, a linter that found problems, a curl that got a non-2xx. Make faithfully reports the non-zero exit.

FAIL  tests/test_orders.py::test_total
make: *** [Makefile:58: test] Error 1

2. A required tool is missing (Error 127)

The recipe calls a binary that is not installed or not on PATH. Exit 127 is the shell’s “command not found”.

/bin/sh: 1: shellcheck: not found
make: *** [Makefile:70: lint] Error 127

3. Per-line shell semantics — each recipe line is its own shell

Make runs each recipe line in a separate shell by default, and there is no set -e across lines. A cd on one line does not carry to the next, and a failure mid-line inside a && chain aborts with the command’s status.

build:
	cd src        # this cd is lost on the next line
	gcc -c app.c  # runs in the original directory, may fail

4. A shell pipeline masks or surfaces the wrong status

By default make checks the exit status of the whole recipe line. In a pipeline a | b, the status is b’s unless .SHELLFLAGS/pipefail is set, so a failing a can be hidden — or a strict pipefail setup surfaces it as Error 1.

5. Errors intentionally or accidentally (un)ignored

A - prefix on a recipe line tells make to ignore that command’s failure; removing it (or a tool that used to warn now errors) turns a previously “passing” build into Error 1.

How to Diagnose

Step 1 — Read the lines above the Error N line. That is where the real message is. Scroll up past make’s summary.

make build 2>&1 | tail -20
app.c:12:5: error: 'retval' undeclared (first use in this function)
make: *** [Makefile:42: build] Error 1

Step 2 — Look at the exact recipe line make named. Makefile:42 tells you which line failed.

sed -n '40,45p' Makefile
build:
	gcc -c -o app.o app.c
	gcc -o app app.o

Step 3 — Run the failing command by hand to see its full output and exit status.

gcc -c -o app.o app.c; echo "exit=$?"
app.c:12:5: error: 'retval' undeclared (first use in this function)
exit=1

Step 4 — Trace the recipe shell to see every command and where it broke. Override the shell to echo commands:

make build SHELL='sh -x'
+ gcc -c -o app.o app.c
app.c:12:5: error: 'retval' undeclared
make: *** [Makefile:42: build] Error 1

Step 5 — For a missing tool, confirm it is on PATH under make.

make lint 2>&1 | grep -i 'not found'
command -v shellcheck || echo "shellcheck not installed"

Fixes

Fix the underlying command failure. Most of the time the tool told you exactly what is wrong — correct the code, the test, or the input:

int retval;
retval = do_work();

Install or provide the missing tool (Error 127).

sudo apt-get install -y shellcheck
# or pin PATH in the Makefile so make finds local tools
export PATH := $(PWD)/node_modules/.bin:$(PATH)

Chain directory changes within a single recipe line so cd persists:

build:
	cd src && gcc -c app.c && gcc -o app app.o

Make the recipe strict on purpose so partial failures don’t slip through. Set a fail-fast shell for the whole Makefile:

SHELL := bash
.SHELLFLAGS := -eu -o pipefail -c

Now any failed command (including in a pipeline) aborts the recipe with a clear status.

Intentionally ignore a command that is allowed to fail with a - prefix — use sparingly:

clean:
	-rm -f app.o app        # ignore "no such file" on a clean tree

See all failing targets at once during a big build with -k (keep going), then fix them together:

make -k 2>&1 | grep 'Error '

What to Watch Out For

  • The Error N line is a summary; the diagnosis is always in the output above it. Do not debug the make line — debug what the recipe printed.
  • Each recipe line runs in its own shell. cd, set -e, and shell variables do not persist across lines unless you join them with && or ; or enable .ONESHELL:.
  • Make does not use set -e semantics by default across a line’s ;-separated commands — set .SHELLFLAGS := -ec (or -eo pipefail) if you want fail-fast behavior.
  • Exit codes are informative: 127 = command not found, 126 = found but not executable, 130 = interrupted (Ctrl-C), 1/2 = the tool’s own error.
  • A leading - on a recipe line silently ignores failures. A build that “passes” but produces nothing may be swallowing errors this way — grep the Makefile for \t-.
Free download · 368-page PDF

Fixed it? Get 500 Automation & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.