Python
Error Handling
Programming
Control Flow
Finally Block

Why can't a 'continue' statement be inside a 'finally' block?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

In Python (before 3.8), placing a continue statement inside a finally block raises SyntaxError: 'continue' not supported inside 'finally' clause. This restriction exists because finally is guaranteed to execute regardless of exceptions, and allowing continue to silently skip out of the finally block could mask exceptions or bypass critical cleanup code. Python 3.8 removed this restriction, but understanding the original reasoning helps avoid subtle bugs when mixing loop control with exception handling.

The Error (Python < 3.8)

python
1for i in range(5):
2    try:
3        if i == 2:
4            raise ValueError("bad value")
5    finally:
6        continue  # SyntaxError in Python < 3.8
7
8# SyntaxError: 'continue' not supported inside 'finally' clause

Why It Was Prohibited

The finally block has a special contract: it always runs, whether the try block succeeds, raises an exception, or executes a return/break. Allowing continue inside finally creates ambiguous behavior:

python
1# Hypothetical problem: what happens to the exception?
2for i in range(5):
3    try:
4        raise ValueError(f"Error at {i}")
5    finally:
6        continue  # Should the exception propagate or be silently swallowed?

If continue runs, it transfers control to the next loop iteration, and the ValueError is silently discarded. This violates the principle that exceptions should be explicitly caught, not implicitly ignored.

Python 3.8+: continue Is Allowed

Starting in Python 3.8 (PEP 601), continue inside finally is legal:

python
1# Python 3.8+
2for i in range(5):
3    try:
4        if i == 2:
5            raise ValueError("skip this")
6    except ValueError:
7        print(f"Caught error at {i}")
8    finally:
9        if i % 2 == 0:
10            continue  # Legal in Python 3.8+
11    print(f"Processing {i}")
12
13# Output:
14# Processing 1
15# Caught error at 2
16# Processing 3

The continue in finally skips the rest of the loop body for even indices.

The Danger: Swallowing Exceptions

Even in Python 3.8+, continue in finally silently discards unhandled exceptions:

python
1for i in range(5):
2    try:
3        if i == 3:
4            raise RuntimeError("Critical error!")
5    finally:
6        continue  # Swallows the RuntimeError silently!
7
8print("Loop finished — no error was ever seen")
9# The RuntimeError at i=3 is completely lost

This is extremely dangerous. The exception is raised, finally runs, continue transfers control to the next iteration, and the exception disappears without being caught or logged.

Safe Patterns

Handle Exceptions Explicitly

python
1for i in range(5):
2    try:
3        result = 10 / (i - 2)  # Raises ZeroDivisionError when i == 2
4    except ZeroDivisionError:
5        print(f"Skipping {i} (division by zero)")
6        continue  # Safe — inside except, not finally
7    finally:
8        print(f"Cleanup for {i}")
9
10    print(f"Result: {result}")

Use a Flag Instead

python
1for i in range(5):
2    should_skip = False
3    try:
4        result = risky_operation(i)
5    except SomeError:
6        should_skip = True
7    finally:
8        cleanup(i)  # Always runs
9
10    if should_skip:
11        continue
12
13    process(result)

Separate Cleanup from Control Flow

python
1for item in items:
2    try:
3        resource = acquire(item)
4        try:
5            process(resource)
6        except ProcessingError:
7            continue  # Skip to next item — exception is handled
8        finally:
9            resource.close()  # Cleanup always runs
10    except AcquisitionError:
11        log_error(item)
12        continue

break and return in finally

The same concern applies to break and return:

python
1def find_item(items):
2    for item in items:
3        try:
4            if item == "target":
5                return item  # return inside try
6        finally:
7            print(f"Finally for {item}")
8            # If 'return' were here, it would override the try's return value
9
10# 'break' in finally also silences exceptions (Python 3.8+)
11for i in range(5):
12    try:
13        raise ValueError("error")
14    finally:
15        break  # Swallows the ValueError, exits the loop

Comparison Across Languages

Languagecontinue in finallyBehavior
Python < 3.8SyntaxErrorProhibited
Python 3.8+AllowedSilently swallows exceptions
JavaCompile errorProhibited
C#Compile errorProhibited
JavaScriptAllowedSilently swallows exceptions

Java and C# also prohibit continue (and break, return) in finally blocks to prevent exception swallowing.

Common Pitfalls

  • Using continue in finally to skip iterations (Python 3.8+): While legal, this silently discards any pending exception from the try block. If an unhandled exception was about to propagate, continue swallows it without any indication. Always handle exceptions in except blocks instead.
  • Confusing finally with except for control flow: finally is for cleanup (closing files, releasing locks), not for handling errors. Place continue, break, and error-recovery logic in except blocks, not in finally.
  • Putting return in finally that overrides the try return value: return in finally replaces whatever value was being returned from try or except. This can produce confusing results where a function returns a value unrelated to its actual logic.
  • Assuming break in finally propagates exceptions: break inside finally (Python 3.8+) exits the loop and silently discards any pending exception, just like continue. The exception is lost without being logged or handled.
  • Writing code that depends on Python 3.8+ behavior: If your code uses continue in finally, it will break on Python 3.6/3.7 with a SyntaxError. Check your minimum Python version before using this pattern.

Summary

  • Python < 3.8 raises SyntaxError for continue in finally — it was prohibited to prevent silent exception swallowing
  • Python 3.8+ allows it, but continue in finally silently discards any pending exception
  • Place loop control (continue, break) in except blocks, not in finally
  • Use finally only for cleanup code (closing resources, releasing locks)
  • Java and C# also prohibit continue in finally for the same safety reasons

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.