How to solve the "here-document at line 1 delimited by end-of-file (wanted 'EOF')" warning
Recently, I ran into a frustrating issue with a shell script that uses heredocs. The closing EOF had indentation, so the shell didn’t recognize it as the closing tag. Everything after it kept getting added to the file, breaking the whole thing and the logs were showing this warning: here-document at line 1 delimited by end-of-file (wanted 'EOF') warning.
What is a Heredoc?
First of all some theory. A heredoc (here-document) is a shell syntax that allows you to pass multi-line input to a command. It starts with << followed by a delimiter (usually EOF) and ends when that same delimiter appears on its own line. Heredocs are commonly used to create files, pass multi-line strings to commands, or provide input to scripts.
The problem
With heredocs, the closing EOF must be at the beginning of the line. No spaces, no tabs, nothing.
Here’s what went wrong:
cat > /tmp/myfile.txt << EOF
This is line 1
This is line 2
EOF # WRONG: indented!
echo "File created successfully"
The shell treated the indented EOF as regular content instead of a closing delimiter and reached the end of the file looking for that delimiter. So the file ended up with:
This is line 1
This is line 2
EOF
The fix
Just put EOF at the start of the line:
cat > /tmp/myfile.txt << EOF
This is line 1
This is line 2
EOF
echo "File created successfully"
What to do if you need indentation
If you want the closing delimiter indented within an indented block (like inside a function or if statement), use <<- instead of <<. This strips leading tabs (not spaces):
if true; then
cat > /tmp/myfile.txt <<- EOF
This is line 1
This is line 2
EOF
fi
You can also quote the delimiter to prevent variable expansion. Variable expansion is when the shell replaces $VARIABLE with its actual value—quoting the delimiter keeps the variable name as literal text instead:
cat > /tmp/myfile.txt << 'EOF'
This is line 1
This is $VARIABLE # Won't be expanded
EOF
That’s it. Keep EOF unindented unless you’re using <<- with tabs.