Skip to main content

How to Resolve Error "CS0163: Control cannot fall through from one case label ('label') to another" in C#

The Compiler Error CS0163 is a control flow safety error. The message reads: "Control cannot fall through from one case label ('case X:') to another".

In languages like C or C++, if you omit a break statement at the end of a case block, the program automatically executes the code in the next case block. This behavior is called Fall-Through. C# considers implicit fall-through to be a common source of bugs (executing code unintentionally). Therefore, C# forbids falling through from one non-empty case to another. Every case that contains statements must explicitly end with a jump statement.

This guide explains how to properly terminate case blocks and how to achieve fall-through behavior explicitly if needed.

Understanding the "No Fall-Through" Rule​

If a case block contains any instructions (even just a variable declaration or a console print), it is considered "non-empty." A non-empty case must end with one of the following keywords:

  • break (Exits the switch)
  • return (Exits the method)
  • throw (Exits via exception)
  • goto case <value> (Jumps to another case)
  • goto default (Jumps to default)

If the compiler detects a path where execution reaches the end of the case block and tries to "fall" into the next one, it raises CS0163.

Scenario 1: The Forgotten Break (Common Mistake)​

This is the most frequent cause. A developer writes logic for a case but simply forgets to type break; at the end.

Example of error​

public void ProcessLevel(int level)
{
switch (level)
{
case 1:
Console.WriteLine("Easy Mode");
// ⛔️ Error CS0163: Control cannot fall through from one case label ('case 1:') to another.
// Execution hits this line and tries to fall into 'case 2', which is forbidden.

case 2:
Console.WriteLine("Medium Mode");
break;
}
}

Solution: Add Break​

Simply add the break; statement.

public void ProcessLevel(int level)
{
switch (level)
{
case 1:
Console.WriteLine("Easy Mode");
break; // ✅ Correct: Safely exits the switch

case 2:
Console.WriteLine("Medium Mode");
break;
}
}

Scenario 2: Incomplete Conditional Paths​

If you use if/else statements inside a case, every possible branch must contain a jump statement. If one branch (e.g., the else) allows execution to reach the bottom of the case, the error occurs.

Example of error​

public void CheckAdmin(string role, bool isActive)
{
switch (role)
{
case "Admin":
if (isActive)
{
Console.WriteLine("Welcome Admin");
return; // Exits method (Valid)
}
// ⛔️ Error CS0163: What if 'isActive' is false?
// The code falls out of the 'if' and hits the bottom of 'case "Admin"',
// trying to fall into 'default'.

default:
Console.WriteLine("Access Denied");
break;
}
}

Solution: Cover All Paths​

Ensure the loop or condition has a definitive exit for all scenarios.

public void CheckAdmin(string role, bool isActive)
{
switch (role)
{
case "Admin":
if (isActive)
{
Console.WriteLine("Welcome Admin");
return;
}
else
{
Console.WriteLine("Inactive Admin");
break; // ✅ Correct: The 'else' path now breaks properly
}

default:
Console.WriteLine("Access Denied");
break;
}
}

Solution 1: Explicit Fall-Through (goto case)​

If you actually want the logic to execute Case A and then immediately execute Case B (the behavior of C++ fall-through), you must be explicit using goto case.

public void ProcessPayment(int status)
{
switch (status)
{
case 1: // "Authorized"
Console.WriteLine("Payment Authorized.");
// We want to proceed immediately to "Capture" logic (Case 2)
// ✅ Correct: Explicitly jump to case 2
goto case 2;

case 2: // "Captured"
Console.WriteLine("Payment Captured.");
break;
}
}

Solution 2: Stacked Cases (Empty Cases)​

There is one exception to the rule: Empty case labels are allowed to fall through. This allows you to group multiple inputs that should execute the exact same code.

public void CheckDay(string day)
{
switch (day)
{
// ✅ Correct: These cases are empty, so they fall through to "Sunday".
case "Saturday":
case "Sunday":
Console.WriteLine("It's the weekend!");
break;

default:
Console.WriteLine("Work day.");
break;
}
}
note

If you added even a single line of code to case "Saturday", it would no longer be empty, and falling through to Sunday would trigger CS0163.

Conclusion​

CS0163 enforces intention. It prevents you from accidentally running code you didn't mean to.

  1. Standard Case: Always end a non-empty case with break; or return;.
  2. Grouping Inputs: Use stacked empty cases (case 1: case 2:) to share logic.
  3. Sharing Logic: If you need to run one case and then another, use goto case <val>;.