IndentationError
Core Python Errors and Exceptions Error explained

Python IndentationError

1IndentationError: overview

An IndentationError means the spaces at the start of a line don't match the block structure Python expected, for example a missing body after a colon or a stray extra indent.

GoalBy the end you can read an IndentationError message, tell its four variants apart and fix each one, including mixed tabs and spaces.

Before this lesson: Python Syntax, Python SyntaxError

2IndentationError: diagram

Python IndentationErrorWrong: no indentif score > 50:print("pass")# IndentationError: expected# an indented block after# 'if' statement on line 1Right: 4 spacesif score > 50: print("pass")# the body is one level# deeper than its header# (4 spaces)indent
A line ending with a colon opens a block, and the lines inside it must sit four spaces deeper. Without that indent Python stops before running anything.

3IndentationError: explained step by step

An IndentationError means Python found a line whose leading whitespace doesn't match the block structure it expected. Python has no curly braces: the spaces at the start of a line are the structure. A line that ends with a colon opens a block, and every line inside that block must be indented by the same amount.

IndentationError is a special kind of SyntaxError. Python checks the layout of the whole file before it runs a single line, so a bad indent on line 40 stops your program even though lines 1 to 39 were fine. If you want a refresher on the layout rules, see Python syntax.

A small helper to trigger the error safely

A real indentation mistake is raised while the file is being compiled, so you can't catch it with a normal try around the broken line. In this lesson we hand the source code to compile() as a string and catch the error there. That lets every demo run without crashing the page.

Python
def show_error(source):
    try:
        compile(source, "demo.py", "exec")
        print("ok: no indentation problem")
    except IndentationError as err:
        print(f"{type(err).__name__}: {err.msg} (line {err.lineno})")

show_error("price = 10\nprint(price)\n")
show_error("price = 10\n    print(price)\n")

How to read an IndentationError traceback

  File "main.py", line 3
    print("pass")
    ^
IndentationError: expected an indented block after 'if' statement on line 2
  1. Read the last line first. It names the exact problem and often the statement that caused it.
  2. The line number at the top points at the line Python could not accept. For a missing body that is the line after the colon, while the message tells you which header (here line 2) was waiting for it.
  3. If the code looks perfectly aligned but still fails, the difference is invisible: a tab where you expected spaces. Turn on "show whitespace" in your editor.

Why "expected an indented block" happens

Every header that ends in a colon (if, elif, else, for, while, def, class, try, except, with) needs at least one indented line under it. If the next line starts at the same column, Python reports the header it was waiting on. Compare it with how if statements, for loops and functions are written.

Python
def show_error(source):
    try:
        compile(source, "demo.py", "exec")
        print("ok")
    except IndentationError as err:
        print(f"{err.msg} (line {err.lineno})")

show_error("score = 80\nif score > 50:\nprint('pass')\n")
show_error("def greet(name):\nprint(name)\n")
show_error("for n in range(3):\nprint(n)\n")
show_error("for n in range(3):\n    print(n)\n")

The fix is always the same: indent the body by four spaces, or remove the header if you didn't mean to start a block.

An empty block needs pass, not just a comment

A comment is not a statement, so a block that contains only a comment is still empty. When you want to leave a body for later, write pass as a placeholder.

Python
def show_error(source):
    try:
        compile(source, "demo.py", "exec")
        print("ok")
    except IndentationError as err:
        print(f"{err.msg} (line {err.lineno})")

show_error("def apply_coupon(cart):\n    # TODO later\n")
show_error("def apply_coupon(cart):\n    pass\n")

Why "unexpected indent" happens

The opposite problem: a line is indented but nothing opened a block above it. This usually comes from a stray space at the start of a line, or from pasting a snippet that carried its original indentation with it. A line only gets deeper after a line ending with a colon.

Python
def show_error(source):
    try:
        compile(source, "demo.py", "exec")
        print("ok")
    except IndentationError as err:
        print(f"{err.msg} (line {err.lineno})")

show_error("total = 5\n    tax = 1\n")
show_error("total = 5\ntax = 1\n")

Why "unindent does not match any outer indentation level" happens

When a block ends, the next line must return to a column that an earlier line already used. If you step back to a column that was never used, Python can't tell which block you mean. Here the body uses 8 spaces, and the next line uses 4 spaces, which does not match the header's column (0) either.

Python
def show_error(source):
    try:
        compile(source, "demo.py", "exec")
        print("ok")
    except IndentationError as err:
        print(f"{err.msg} (line {err.lineno})")

show_error("def total():\n        a = 1\n    b = 2\n")
show_error("def total():\n    a = 1\n    b = 2\n")

This also happens when an else is lined up one or two spaces away from the if it belongs to. Use the same number of spaces for every line at the same level.

Why a tab causes TabError

A tab and four spaces can look identical on screen, but Python treats them as different characters. If one block mixes them, Python raises TabError, a subclass of IndentationError.

Python
mixed = "def total():\n    a = 1\n\tb = 2\n"
try:
    compile(mixed, "demo.py", "exec")
except IndentationError as err:
    print(type(err).__name__ + ":", err.msg)
    print(repr(mixed.split("\n")[2]))

Printing a line with repr() shows \t for a tab, which makes the invisible visible. Pick four spaces everywhere, as recommended by Python's style guide.

Nested blocks and copy-paste

Each level of nesting adds four more spaces. When you paste code into a loop, the whole pasted chunk must be shifted together, not just its first line. Most editors do this with Tab and Shift+Tab on a selection. Deeper structures such as nested loops make the rule easy to see: the inner body is always four spaces deeper than its header.

Editor settings that prevent these errors

  • Turn on show whitespace (dots for spaces, arrows for tabs).
  • Set the editor to insert spaces when you press Tab, with a width of 4.
  • Use Convert indentation to spaces when a file with tabs arrives.
  • Select pasted code and re-indent it as one block instead of fixing lines one at a time.

4IndentationError: syntax

if condition:
    body_line_1        # 4 spaces
    body_line_2        # same indent for the whole block
    if other:
        inner_body     # 8 spaces: one more level
next_statement         # back to column 0 ends the blocks

def placeholder():
    pass               # empty body needs a statement

5IndentationError: run the example

Press Run (or Ctrl + Enter). The output (step 6) appears directly below the code. Change anything and run it again.

Interactive example
broken = (
    "total = 0\n"
    "for price in [4, 6, 10]:\n"
    "total += price\n"
    "print(total)\n"
)

try:
    compile(broken, "cart.py", "exec")
except IndentationError as err:
    print(type(err).__name__ + ":", err.msg)
    print("problem is on line", err.lineno)
    print("offending text:", err.text.strip())

fixed = broken.replace("\ntotal +=", "\n    total +=")
exec(fixed)
Expected outputIndentationError: expected an indented block after 'for' statement on line 2
problem is on line 3
offending text: total += price
20

7IndentationError: how the example works

Hover or tap a step to highlight its lines in the example above.

  1. Line 1-6broken is Python source stored in a string. The for header on line 2 of that source is followed by total += price at column 0, so the loop has no body.
  2. Line 8-10compile() checks the source without running it. It fails here, which is exactly what happens when Python loads a script with this mistake.
  3. Line 11err.msg holds the message without the (file, line) suffix. It names the for statement waiting for its body.
  4. Line 12-13err.lineno is the line that was not indented (line 3 of the source) and err.text is its content, so you know where to look.
  5. Line 15-16replace() adds four spaces in front of total +=. exec() runs the repaired code, which sums 4 + 6 + 10 and prints 20.

8IndentationError: common mistakes

Writing the body at the same level as the header

✗ Wrong

score = 80
if score > 50:
print("pass")
IndentationError: expected an indented block after 'if' statement on line 2

✓ Right

score = 80
if score > 50:
    print("pass")

The print line must be indented under the if. Press Tab (set to four spaces) at the start of every line of the body.

Leaving a block with only a comment

✗ Wrong

def send_receipt(order):
    # TODO: write this later
IndentationError: expected an indented block after function definition on line 1

✓ Right

def send_receipt(order):
    # TODO: write this later
    pass

Comments don't count as statements. Put pass (or a docstring) in the body until you write the real code.

An extra space before a statement

✗ Wrong

total = 5
 tax = 1
print(total + tax)
IndentationError: unexpected indent

✓ Right

total = 5
tax = 1
print(total + tax)

A line may only be indented when the line above it ends with a colon. Remove the stray space.

Dedenting to a level that doesn't exist

✗ Wrong

def total():
        a = 1
    b = 2
IndentationError: unindent does not match any outer indentation level

✓ Right

def total():
    a = 1
    b = 2

Every line in the same block needs the same indentation. Use four spaces for each level and line up b with a.

Mixing a tab with spaces

✗ Wrong

def total():
    a = 1
	b = 2
TabError: inconsistent use of tabs and spaces in indentation

✓ Right

def total():
    a = 1
    b = 2

Replace the tab with four spaces. Configure your editor to insert spaces when you press Tab so it can't happen again.

9IndentationError: exercises

Write your answer, then press Check. The checks run in your browser.

1. Indent the function body

Fix the bug Easy

apply_discount(price, percent) should return the price after taking off percent percent, but the file raises an IndentationError. Fix the indentation only, so apply_discount(200, 10) returns 180.0.

Your code
def apply_discount(price, percent):
discount = price * percent / 100
    return price - discount

print(apply_discount(200, 10))

2. Predict the error messages

Predict the output Easy

Read the code and type exactly what it prints. Each snippet is compiled, not run, so only the layout matters.

Read this code
snippets = [
    "if True:\n    print('a')\n",
    "if True:\nprint('a')\n",
    "x = 1\n    y = 2\n",
    "def f():\n    pass\n",
]

for number, source in enumerate(snippets, start=1):
    try:
        compile(source, "snippet", "exec")
        print(number, "ok")
    except IndentationError as err:
        print(number, err.msg)

2 more exercises → 6 more examples

Finished this lesson?
Progress is saved in this browser — create a free account to keep it across devices.

Questions learners ask

Should I use tabs or spaces in Python?

Use four spaces per level. Python 3 refuses to mix tabs and spaces inside one block (TabError), and the official style guide recommends spaces. Set your editor to insert spaces when you press the Tab key and you can forget about the difference.

My code looks correctly indented but I still get an IndentationError. Why?

The difference is probably invisible: a tab among spaces, a non-breaking space pasted from a web page, or trailing whitespace on the line above. Turn on 'show whitespace' in your editor, or print the line with repr() to see the exact characters, then re-indent with spaces.

Is an IndentationError the same as a SyntaxError?

It is a more specific kind. IndentationError is a subclass of SyntaxError, and TabError is a subclass of IndentationError. All three are raised while Python reads the file, before any line runs, so you can't catch them with try/except around the broken line itself.

Further reading

10Next lesson

Up nextPython ValueErrorA ValueError means a function received a value of the correct type but with content it cannot accept, such as int() giv…

Related:
Python if, elif and elsePython for LoopsPython FunctionsPython SyntaxError

← Python SyntaxError · All Errors and Exceptions lessons · Practise in the IDE