Every program ends with an exit code, a whole number, and batch files read it as the
error level. By convention 0 means success and anything else is a failure or a
result, but each program decides. Microsoft’s pages say “If a command completes an operation
successfully, it returns an exit code of zero (0) or no exit code” (cmd).
Reading it
| Syntax | Meaning |
|---|---|
if errorlevel n command | True when the exit code of the last program is n or more. So if errorlevel 1 means “1 or higher” and if not errorlevel 1 means “0 or lower”. A test for a set of values is made from highest to lowest |
%ERRORLEVEL% | The exit code as a number, to compare with if %errorlevel% equ 2 or if %errorlevel% neq 0, or to store. Needs command extensions |
cmd1 && cmd2, cmd1 || cmd2 | Run cmd2 on success (code 0) or on failure (Redirection and pipes) |
%=ExitCode% | Undocumented: the last exit code in hexadecimal (Special variables) |
%ERRORLEVEL%is a dynamic variable: if a real variable namedERRORLEVELexists, the real one wins (Microsoft’sifpage). A script that doesset errorlevel=0breaks the real value until it is deleted withset errorlevel=.- Inside a parenthesised block
%errorlevel%is read when the block is read, so it does not show a code set by a command in the same block. Useif errorlevel n, which is read when it runs, or delayed expansion!errorlevel!. - Modern exit codes are 32-bit signed numbers;
-1and 4294967295 are the same exit code. COMMAND.COM on DOS reads one byte (0 to 255).
Setting it
| Syntax | Effect |
|---|---|
exit /b n | Ends the batch file or call :label subroutine and sets the error level to n (Microsoft). Without n the error level is left as it is |
exit n | Ends cmd.exe itself, with process exit code n. Run at the prompt, exit /b also leaves cmd.exe |
goto :eof | Ends the file or subroutine and leaves the error level as it is |
cmd /c file.bat | The process exit code of the new cmd.exe is the error level of the batch file at its end |
setlocal with an option | Sets the error level to 0, or to 1 if extensions are not available (Microsoft’s setlocal page) |
verify other 2>nul | An invalid argument that sets the error level to non-zero, used to test for extensions before setlocal enableextensions |
(call ), (call) | Reported idioms: (call ) with a space sets the error level to 0 and (call) sets it to 1, without running anything |
The error level of a batch file that ends normally is that of its last command. A file that runs
another with call gets its exit code in %errorlevel%; one that runs it without
call never gets control back.
Which commands set it
- Programs always set it when they end.
- Many built-in commands set it only when they fail and leave it as it was when they succeed, so an old error level survives a successful
copyordel. A script that needs a clean value clears it first. - When command extensions are disabled the interpreter does not set
ERRORLEVELat all (Microsoft’ssetlocalpage). - A command that is not found sets 9009 on current Windows (reported). A
Label not founderror stops the batch file. - .bat against .cmd. It is reported (SS64) that a few commands that change the environment or associations (
set,path,prompt,assoc,ftypeand related ones) always set the error level in a.cmdfile, to 0 on success, but only set it when they fail in a.batfile. This is the one documented-by-others difference between the two extensions, and Microsoft’s command pages do not describe it.
Codes of common programs
| Program | Codes |
|---|---|
find | 0 a match was found, 1 none was found, 2 an error (reported) |
findstr | 0 a match, 1 no match; others for errors (reported) |
fc | 0 the files are the same, 1 they differ, 2 a file could not be found (reported) |
choice | The position of the key chosen, from 1; 0 when Ctrl+C was pressed (reported) |
robocopy | A set of bits that add together: 1 files copied, 2 extra files, 4 mismatched, 8 some failed, 16 serious error; a code below 8 is a success. See Microsoft’s robocopy page |
xcopy | 0 files copied, 1 no files found, 2 stopped by the user, 4 initialisation error, 5 disk write error (reported) |
| Windows applications | Whatever the program returns; Windows system error codes are listed in Microsoft’s Debug system error codes |
An example
@echo off
robocopy "%~1" "%~2" /e /r:1 /w:1 >nul
if %errorlevel% geq 8 (
echo Copy failed with code %errorlevel%
exit /b %errorlevel%
)
findstr /c:"ERROR" "%~2\build.log" >nul && echo The log holds errors.
if errorlevel 1 echo (no ERROR line found)
exit /b 0
exit /b with the same code.Not described
Unknown
- Reference: the
.batand.cmddifference, the 9009 code, the(call)idioms and the codes listed as reported forfind,findstr,fc,choiceandxcopyare not from the Microsoft pages fetched for this reference and were not run on Windows for it.