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