Skip to main content

How to Resolve Error "CS0153: A goto case is only valid inside a switch statement" in C#

The Compiler Error CS0153 is a control flow context error. The message reads: "A goto case is only valid inside a switch statement".

In C#, the goto keyword has two distinct forms:

  1. goto LabelName;: Jumps to a specific named label anywhere in the current scope.
  2. goto case Constant; (or goto default;): Jumps specifically to a case label within a switch statement.

This error occurs when you use the second form (goto case) outside of a switch block. The compiler rejects this because without a surrounding switch, the concept of "case" does not exist.

Understanding goto case vs. goto label

The goto case statement is designed for Fall-Through logic (or re-directing logic) strictly within a switch. It relies on the switch's internal jump table to find the target value.

  • Valid: Inside switch(x) { ... goto case 5; ... }
  • Invalid: Inside if (x) { goto case 5; }

If you are not inside a switch, the compiler cannot resolve the target "case 5".

Scenario 1: Using goto case in if statements

This is the most common syntax error. A developer might try to simulate switch behavior using if-else logic but accidentally uses the switch-specific jump syntax.

Example of error:

public void ProcessInput(int choice)
{
if (choice == 1)
{
Console.WriteLine("Step 1");
// Logic for step 1
}
else if (choice == 2)
{
Console.WriteLine("Step 2");

// ⛔️ Error CS0153: A goto case is only valid inside a switch statement.
// The compiler sees 'goto case' but there is no 'switch' wrapping this code.
goto case 1;
}
}

Solution 1: Convert to a Switch Statement

If your logic relies on jumping between cases based on values, the code structure should fundamentally be a switch statement.

Solution: wrap the logic in a switch block.

public void ProcessInput(int choice)
{
// ✅ Correct: The 'switch' defines the context for 'case' labels.
switch (choice)
{
case 1:
Console.WriteLine("Step 1");
break;

case 2:
Console.WriteLine("Step 2");

// ✅ Correct: Valid jump to another case within the same switch
goto case 1;
}
}
note

The same rule applies to goto default;. It can only be used if there is a switch block containing a default: label.

Solution 2: Use Standard Labels

If you cannot use a switch statement (perhaps because your conditions are complex boolean expressions rather than simple constant checks), you must use standard Labels and the generic goto LabelName; syntax.

Solution: define a label identifier followed by a colon (:).

public void ProcessInput(int choice)
{
if (choice == 1)
{
// Define a standard label
Step1:
Console.WriteLine("Step 1");
}
else if (choice == 2)
{
Console.WriteLine("Step 2");

// ✅ Correct: Jump to the named label 'Step1'
goto Step1;
}
}
warning

Refactoring Advice: Heavy use of goto (Spaghetti Code) makes applications hard to debug and maintain. If you find yourself jumping backward or between blocks frequently, consider refactoring the shared logic into a separate Method and calling that method from both places.

Conclusion

CS0153 is a context error.

  1. Identify the Keyword: Are you using goto case or goto default?
  2. Check the Container: Are those statements strictly inside a switch { ... } block?
  3. The Fix:
    • If you want switch behavior, wrap your code in a switch.
    • If you are in an if/else or loop, use standard labels (MyLabel:) and goto MyLabel;.