Skip to main content

How to Resolve Error "CS0140: The label 'label' is a duplicate" in C#

The Compiler Error CS0140 is a Naming Conflict error related to flow control. The message reads: "The label 'LabelName' is a duplicate".

In C#, a Label (an identifier followed by a colon, e.g., Start:) marks a specific location in your code that you can jump to using the goto statement. The scope of a label is the entire method in which it is declared. This means you cannot use the same label name twice within the same method, even if they are placed inside different blocks (like inside an if or while loop).

This guide explains the scoping rules of labels and how to resolve duplicates.

Understanding Label Scope

Variables in C# obey block scope (they live inside { ... }). Labels, however, generally obey Method Scope.

When you define a label, it must be unique within that function. The compiler needs a unique target for a goto statement. If there are two labels named Exit:, writing goto Exit; becomes ambiguous—the compiler wouldn't know which one you meant.

warning

Usage Note: Use of goto and labels is generally discouraged in modern C# development in favor of structured control flow (for, while, break, return, methods), as goto can make code difficult to read and maintain ("Spaghetti Code").

Scenario 1: Copy-Paste Duplication

The most common cause is copying a chunk of code that contains a label and pasting it later in the same method without renaming the label.

Example of error

public void ProcessData()
{
// First logic block
int x = 10;
if (x > 5) goto Error;

// ... code ...

Error: // First definition
Console.WriteLine("Error in block 1");

// Second logic block (Copied & Pasted)
int y = 2;
if (y < 5) goto Error;

// ⛔️ Error CS0140: The label 'Error' is a duplicate
Error: // Second definition
Console.WriteLine("Error in block 2");
}

Solution: Unique Names

Rename the second label to make it distinct.

public void ProcessData()
{
// First logic block
int x = 10;
if (x > 5) goto Error1;

Error1:
Console.WriteLine("Error in block 1");

// Second logic block
int y = 2;
if (y < 5) goto Error2;

// ✅ Correct: Unique label name
Error2:
Console.WriteLine("Error in block 2");
}

Scenario 2: Nested Blocks and Scope

Developers often assume that because a label is inside curly braces { }, it is hidden from the rest of the method. This is incorrect. A label inside an if block collides with a label inside an else block or a subsequent loop.

Example of error

public void CheckStatus(bool isValid)
{
if (isValid)
{
// This label is visible to the WHOLE method, not just this 'if'
Finished:
Console.WriteLine("Valid");
}
else
{
// ⛔️ Error CS0140: The label 'Finished' is a duplicate.
// You cannot reuse it here, even though it's a different block.
Finished:
Console.WriteLine("Invalid");
}
}

Solution: Shared Label

If the logic is meant to converge (both paths go to the same end), move the label outside the blocks.

public void CheckStatus(bool isValid)
{
if (isValid)
{
Console.WriteLine("Valid");
goto Finished; // Jump out
}
else
{
Console.WriteLine("Invalid");
goto Finished; // Jump out
}

// ✅ Correct: Defined once, used by both blocks
Finished:
Console.WriteLine("Done.");
}

Solution: Refactoring Logic

If you find yourself running into CS0140 frequently, it is a strong sign that your method is doing too much or relying too heavily on goto. The best solution is often to extract the logic into separate methods.

Refactoring Example: Instead of one giant method with multiple Error: labels, split the code.

public void ProcessData()
{
ProcessPart1();
ProcessPart2();
}

private void ProcessPart1()
{
// Uses 'Error' label internally
// ...
Error:
Console.WriteLine("Part 1 Failed");
}

private void ProcessPart2()
{
// ✅ Correct: This 'Error' label is valid because
// it is in a completely different method scope.
// ...
Error:
Console.WriteLine("Part 2 Failed");
}

Conclusion

CS0140 ensures that jump targets are unambiguous.

  1. Check Scope: Remember that labels are visible to the entire method, not just the surrounding brackets.
  2. Rename: If you need two distinct jump points, give them distinct names (Exit1, Exit2).
  3. Reuse: If different paths lead to the same outcome, define the label once at the end of the logic.
  4. Refactor: Consider moving logic into separate methods to isolate scopes and improve readability.