“Unexpected EOF” means the parser reached the end of your file while it was still waiting for something: a closing bracket, a closing quote, the fi that ends an if, or the rest of a data file. The error is reported at the last line, but the mistake is almost always earlier, at the place where you opened something and never closed it.
The wording differs by tool, but the cause is the same. Here are the messages you are likely to see, with the output I got from the tools named (Python 3.12, Node 22, g++, Bash, Go).
| Where | Message | Usual cause |
|---|---|---|
| Python (3.10 and newer) | SyntaxError: '(' was never closed |
Unclosed bracket; Python points at the opening one |
| Python | unterminated string literal / unterminated triple-quoted string literal |
Missing closing quote |
| Python | EOFError: EOF when reading a line |
input() called but there is no more input |
| JavaScript | SyntaxError: Unexpected end of input |
Missing }, ) or ] |
| JavaScript | SyntaxError: Unexpected end of JSON input |
JSON.parse got an empty or cut-off string |
| C / C++ | error: expected '}' at end of input, unterminated comment |
Missing brace, unclosed /* |
| Bash | syntax error: unexpected end of file |
Missing fi, done or esac, or Windows line endings |
| Bash | unexpected EOF while looking for matching `"' |
Unclosed quote |
| Go | unexpected EOF (io.ErrUnexpectedEOF), unexpected end of JSON input |
Input stream or JSON ended early |
| Java | reached end of file while parsing |
Missing closing brace |
You may find older posts that quote SyntaxError: unexpected EOF while parsing for Python. That is the message from Python 3.9 and earlier. Newer versions are more helpful because they name the bracket or quote that was left open.
Two different kinds of “EOF” problem
Before you start debugging, decide which of these you have, because the fixes have nothing in common.
- Your source code is incomplete. The compiler or interpreter hit the end of the file inside a block, string or comment. The fix is in your code.
- Your program was reading data that stopped early. A JSON file was truncated, a download failed halfway,
input()had nothing to read, or a network connection closed. The fix is in the data or in how you handle a missing input.
If the message mentions “parsing”, “syntax” or a line number in your own source, it is the first kind. If it appears at runtime, from a call such as json.loads, input(), io.ReadFull or gzip, it is the second.
Kind 1: incomplete source code
Unclosed brackets and parentheses
This is the most common cause. A missing ) on one line makes the parser keep reading, treating every following line as part of the same expression, until the file ends.
def greet():
print("hi"
Python 3.12 reports:
File "a.py", line 2
print("hi"
^
SyntaxError: '(' was never closed
The caret points at the opening parenthesis, which is exactly where you need to look. Older Pythons and many other languages report the error on the last line instead, and then you have to search backwards.
In JavaScript the same mistake gives a message with no useful location:
function f() {
if (x) {
return 1;
SyntaxError: Unexpected end of input
Two missing braces here, and the error says nothing about which. Use your editor’s bracket matching (in VS Code, put the cursor next to a brace and the partner is highlighted, or use “Go to Bracket”), or auto-format the file. A formatter that indents everything under the wrong brace makes the problem visible at once.
Unclosed strings
A missing closing quote swallows the rest of the line, or in a triple-quoted string, the rest of the file:
s = """abc
SyntaxError: unterminated triple-quoted string literal (detected at line 1)
Syntax highlighting is your friend here. If the colors of everything after one line suddenly turn into “string color”, that line is the culprit. Also check for a quote character inside the string that you forgot to escape, such as 'don't'.
Unclosed comments
In C, C++, Java and JavaScript, a /* without a matching */ comments out everything after it:
b.cpp:1:1: error: unterminated comment
1 | /* open
| ^
Search the file for /* and check that each has its partner. This often happens when someone comments out a block of code that already contains a */, because comments do not nest.
Missing braces in C, C++ and Java
#include <iostream>
int main() {
std::cout << 1;
a.cpp:3:18: error: expected '}' at end of input
a.cpp:2:12: note: to match this '{'
g++ even adds a note naming the brace that was never matched. Read the notes under the error, not just the first line. In Java the equivalent is reached end of file while parsing. It is one of the first errors beginners hit, and it simply means a class or method is missing its closing }.
Bash: missing fi, done or esac
Shell scripts give this error when a block is never closed:
if [ -f x ]; then
echo hi
a.sh: line 3: syntax error: unexpected end of file
Every if needs fi, every for or while needs done, every case needs esac. An unclosed quote gives the related unexpected EOF while looking for matching message.
There is a second Bash cause that confuses people because the script looks fine. If you edited it on Windows and saved with CRLF line endings, Bash sees a stray carriage return at the end of each line. I created a three-line script with CRLF endings (if true; then, echo hi, fi) and Bash reported syntax error: unexpected end of file even though every block was closed. Convert the file with dos2unix script.sh, or sed -i 's/\r$//' script.sh, and set your editor to LF line endings for shell scripts.
One more: a here-document whose terminator is missing. Bash prints warning: here-document at line 1 delimited by end-of-file (wanted `EOF') and runs anyway, which is easy to miss.
A method that finds the cause quickly
- Read the first error, not the last. Fix the first message in the output and rebuild. Later errors are usually fallout.
- Look for the opening, not the end. Python 3.10+ and g++ tell you which bracket is unmatched. If your tool does not, auto-format the file and look for the point where the indentation stops making sense.
- Bisect. Comment out or delete the second half of the file (or move it to a scratch file). If the error goes away or moves, the problem is in the half you removed. Repeat. For a 300-line file this takes about eight rounds at most.
- Check the usual suspects in this order: the last function you edited, a recently pasted block, a string containing quotes, a comment you toggled.
- Let the tool check it without running.
python3 -m py_compile file.py,node --check file.jsandbash -n script.shparse the file and report syntax errors only.
For Python files you can also check a file in a few lines, which is handy when the code is generated or pasted from somewhere:
import sys
src = open(sys.argv[1]).read()
try:
compile(src, sys.argv[1], "exec")
print("ok")
except SyntaxError as e:
print(e.msg, "line", e.lineno)
On the file with the open parenthesis this prints '(' was never closed line 2.
Kind 2: data or input that ended early
Truncated or empty JSON
Each language words this differently. I fed {"a": [1, 2 and an empty string to each parser:
- Python
json.loads:Expecting ',' delimiter: line 1 column 12 (char 11), and for an empty stringExpecting value: line 1 column 1 (char 0) - Node
JSON.parse:Expected ',' or ']' after array element in JSON at position 11, and for an empty stringUnexpected end of JSON input - Go
json.Unmarshal:unexpected end of JSON input
If you see these when reading an API response or a file, the data is the problem, not your code. Log the raw string before parsing it. Typical causes are an empty response body (a server error or a 204 status), a file still being written by another process, a request that timed out, or a response that was cut at a size limit. Handle the empty case explicitly instead of passing it to the parser.
EOFError from input()
name = input()
Run with no input available (for example python3 in.py < /dev/null, or in an online judge where the test supplies fewer lines than you read):
EOFError: EOF when reading a line
This is not a syntax error. Your loop read more lines than the input had. In competitive programming and interview platforms, read until input ends instead of guessing the count:
import sys
for line in sys.stdin:
print(line.strip().upper())
Or catch the exception around input() and stop the loop.
Truncated archives and streams
I cut a gzip file short and decompressed it. The command line tool said gzip: t3.gz: unexpected end of file, and Python’s gzip module raised EOFError: Compressed file ended before the end-of-stream marker was reached. The cause is almost always an interrupted download or copy. Download again and compare the file size or checksum with the source.
In Go, reading a fixed-size value from a stream that has fewer bytes returns io.ErrUnexpectedEOF (printed as unexpected EOF), while reading from a stream with no bytes at all returns plain io.EOF. The distinction matters: io.EOF means a clean end, io.ErrUnexpectedEOF means the data stopped in the middle of something. Check for it with errors.Is(err, io.ErrUnexpectedEOF) and treat it as corrupt or incomplete input.
Prevent it
- Type the closing bracket or quote right after the opening one, then fill in the middle. Most editors do this automatically.
- Run a formatter on save (Black or Ruff for Python, Prettier for JavaScript, clang-format for C++). Broken structure shows up as strange indentation the moment you save.
- Keep functions short, so a missing brace has fewer places to hide.
- Run a syntax check or linter before running or committing.
- When pasting code from chat or a web page, check the end of the paste. Truncated pastes are a common source of this error.
- For data you read, validate that it is non-empty and handle the parse exception with a message that includes the first few characters of what you received.
If you are new to reading error messages, the lesson on Python syntax errors on AlgoCademy is a short practice exercise. For a broader routine, see how to avoid common syntax errors during coding interviews and how to debug your code step by step.
