In Windows, using batch files to script common tasks has been around for decades. Even though other scripting languages like PowerShell now exist, batch files are still widely used. If you see the goto batch command in a batch file and have always wondered what it does, you’re in luck.
In this tutorial, you will learn how the goto batch command works in batch files with several examples, and where you may still find a use for this older command today!
Prerequisites
As the goto executable is a part of the cmd.exe suite of batch commands, any version of supported Windows will work.
Understanding a Simple goto Command
In a nutshell, the goto command is a way to control the flow of a batch file. Typically, when you execute a batch file, the script executes from top to bottom following each line. But sometimes, you need the script to start executing at a different place in the script. The goto command is perfect for this.
Let’s say you have a batch script with a couple of simple lines to send text to the screen like below.
@echo off
echo Run this line first
echo Run this line second
echo Run this line third
When you run it, as seen below, it sends the three messages to the screen.

Now, perhaps, you’d like to run the third line before the second line. You could cut and paste but for a real batch file, this might not be possible. Instead, you can redirect the batch file with the goto command. To do that, you’ll use the GOTO command combined with a label.
Below you can see three concepts:
- The
gotolabels created by starting with a colon with code underneath calledrun_first. - Comments that start with
::to indicate the code is not executable. - An optional
goto:eofcommand that tells the batch script to finish or jump to the end of the file (eof). Notice the colon vs. the space here. If you simply useGOTO eof, without the colon, the batch script looks for the label of:eofsomewhere in the file and does not jump to the end and return!
When you run the below script, you’ll see that the batch script runs the code in the order that you have the GOTO commands. The goto command changes the flow of the batch script. The first echo command is never run as the batch script jumps to the specified goto command. From that point forward, the script executes line-by-line.
@echo off
:: Start comments. The goto commands reference the labels
GOTO run_first
:: Optional internal goto command that jumps to the end of the script immediately
GOTO:eof
echo This line will never be output
:run_first
echo Run this line first
:: Each label starts with a colon
echo Run this line second
echo Run this line third

Best Practices Using Labels
In the previous example, you defined labels with an underscore. There’s nothing wrong with this approach but there are many other ways to create these labels. There are several caveats to keep in mind, as not just any label will work.
What will work in a label:
- Spaces
- Periods
- Hypens
What won’t work in a label:
- Equal signs (
=) - Semicolons (
;) - Ending with anything other than a space, colon or CR/LF (carriage return / line-feed) or simply pressing Enter.
Adding various control characters will cause the batch script to run forever in a loop and require manual termination.
If you define a label and the goto command cannot find it, you will receive an error indicating “The system cannot find the batch label specified“.
If a label isn’t found searching forward from the GOTO statement to the end of the file,
cmd.exewill restart the search at the beginning of the file.
:: Spaces are OK in labels
GOTO Label with spaces
:Label with spaces
Echo This is from a label with spaces
:: Underscores, hyphens, and periods are all ok
GOTO Label_hyphenated-with.a.period
:Label_hyphenated-with.a.period
Echo This label has an underscore, hyphen, and a period
:: Control characters such as semi-colons (;) or equal signs (=) cannot be used
:: GOTO Label=Equal
:: GOTO Label;Semicolon
:: If you specify a GOTO statement but do not have a corresponding label
:: you will see an error
GOTO Label_nonexisting
In fact, if you use either of the GOTO statements with the equal (=) or semicolons (;),

Using the if Command with the goto Command
Jumping to different points of a batch file is handy but in the previous example, it wasn’t practical. To add more practicality, what if you needed a batch script to run some commands only if a certain condition were true?
The goto command used in conjunction with the if command gives you control over exactly when that jump is made. For example, check out the below example. In this example, the batch file is using the call command to run a program. That program will always return an exit code that’s always represented in the internal ERRORLEVEL variable.
The batch file then checks to see if the ERRORLEVEL variable is not equal to 0. If so, it skips to the end of the script. Otherwise, it runs the echo command to tell you that an error has occurred and then skips to the end of the batch script.
@echo off
:: Executing a call command with a single space after will set the %ERRORLEVEL%
:: environmental variable to 1, but not exiting the overall script.
call
if %ERRORLEVEL% NEQ 0 GOTO End
echo There was an error and the Error Level was set to a non-zero value
GOTO:eof
:: This will never run if there is an error
:End
echo End of the Script
When you run the above script, you’ll see that call returned a non-zero exit code and existed the echo command to tell you an error occurred.

Calling a Subroutine and Using the goto Command
Now that you have learned the basics of a goto statement, how about using the goto command with a subroutine? A subroutine is like a block of code or a function that you can call to execute. Similar to the goto command, there is a call command which also uses labels.
Unlike the goto command, the call command will run code after the label and then return execution to after the original call command when terminated.
In the below example, this batch file is running the subroutine called my_subroutine using the call command. Then, inside of that subroutine, the batch script runs the goto:eof command to jump to the end of the script.
@echo off
:: Use the SET command to get user input and assign that input to the %Text% variable
set /p Text="Enter Text: "
:: Call the subroutine with the label :my_subroutine and pass in the %text% variable
call :my_subroutine %Text%
:: Return here after the subroutine, echo some text, and then end the script
Echo End of the script
GOTO:eof
:: Run everything in the subroutine
:my_subroutine
:: Each variable passed in is sequentially assigned a variable number, i.e %Text% = %1
Echo User Text: %1
:: Jumps to end of the file, which automatically exits the subroutine
GOTO:eof

Special Cases, Bugs, and GOTO Statement Considerations!
As with any command, there are special cases, bugs, and important considerations to keep in mind while using the goto statement in your code.
Command Extensions and the :eof Special Label
You may have noticed that the previous examples used extensive use of the :eof label. cmd.exe has both internal and external commands. Although the goto command is built-in to cmd.exe, the special label :eof is known as a command extension.
Command extensions can actually be disabled, via the following methods:
- Set the DWORD registry key
HKCU\Software\Microsoft\Command Processor\EnableExtensionsCommandto0. - Use the option,
cmd.exe /e:offto disable command extensions. - Within a batch script, run the command
SETLOCAL DisableExtensions
Although the goto command will work in most contexts, the special label :eof will no longer take effect. You can get around this limitation by using a goto label at the very end of the batch script.
SETLOCAL DisableExtensions
Echo This will display
:: The following command will break the script as the :eof label does not exist
:: GOTO:eof
GOTO End
Echo This will not display
:End

:eof label, whereas the right-hand script properly goes to the end.When you disable command extensions, other
cmd.exefunctionality also ceases to work such as the dynamic variables,%TIME%.
Using Command Groups and Goto Batch Commands in an if Statement
A command group is a series of commands grouped within a parenthesis. This allows an entire set of commands to be operated as one. If you include a goto statement within the command group and an if statement, the remaining conditionals are ignored, such as the below else statement, and the included code is executed.
:: Like before, a call statement without following spaces sets the %ERRORLEVEL% to 1
call
if %ERRORLEVEL% EQU 1 (
GOTO :subsection
:subsection
ECHO This will show since 1 = 1 for the if statement
) else (
:: This will show even though it should not
echo This should not show, but will because GOTO within a command group breaks the if statements
)

if statementAs you might imagine, this could have unintended consequences! If, for example, you included a delete command in the else statement that was not intended to run, this goto statement will break that logic.
Next Steps
Despite there being newer automation languages, such as PowerShell, batch files still find use in many different areas, such as package deployment. Understanding how to structure a script with goto statements and control the script flow becomes invaluable to crafting useful automations!