Skip to main content

How to Resolve Error "CS1028: Unexpected preprocessor directive" in C#

The Compiler Error CS1028 is a syntax error regarding Preprocessor Directives. The message reads: "Unexpected preprocessor directive".

In C#, directives like #if, #else, #elif, and #endif form a logical structure that must be balanced. This error acts as the opposite of CS1027 ("#endif expected"). It occurs when the compiler encounters a closing directive (like #endif) or a continuation directive (like #else) but is not currently inside a matching conditional block. Essentially, you are trying to close a door that was never opened.

This guide explains how to identify and fix these orphaned directives.

Understanding Directive Pairing

Preprocessor directives work in chains.

  • Start: #if
  • Middle (Optional): #elif, #else
  • End: #endif

The compiler maintains a "state stack." When it sees #if, it pushes a state. When it sees #endif, it pops that state. If it encounters #endif or #else while the stack is empty (meaning no #if is currently active), it raises CS1028.

Scenario 1: The Orphaned #endif

This is the most common cause. It usually happens after refactoring code where an #if block was removed, but its corresponding #endif was accidentally left behind, or when an extra #endif was copy-pasted.

Example of error

#define DEBUG

public class Program
{
static void Main()
{
#if DEBUG
System.Console.WriteLine("Debug Mode");
#endif

// ⛔️ Error CS1028: Unexpected preprocessor directive.
// The #if block above is already closed.
// This #endif has no matching #if to close.
#endif
}
}

Solution: Remove the Redundant Directive

Simply delete the extra line.

public class Program
{
static void Main()
{
#if DEBUG
System.Console.WriteLine("Debug Mode");
// ✅ Correct: Block is opened and closed exactly once.
#endif
}
}

Scenario 2: Misplaced #else or #elif

The #else and #elif directives are only valid between an #if and an #endif. If you place them outside of this context, or after the #endif has already appeared, they are considered unexpected.

Example of error

Breaking the chain logic.

#if WINDOWS
// Windows Logic
#endif

// ⛔️ Error CS1028: Unexpected preprocessor directive.
// Because the #endif above closed the block, this #else is stranded.
// It effectively reads: "If nothing... else..."
#else
// Linux Logic
#endif

Solution: Consolidate the Block

Ensure the #else appears before the closing #endif.

#if WINDOWS
// Windows Logic
// ✅ Correct: #else is now part of the chain started by #if WINDOWS
#else
// Linux Logic
#endif
note

Tip: If your conditional blocks are long, it can be hard to track nesting. In Visual Studio, you can hover over an #endif to see which #if it pairs with, helping you identify if the structure is broken.

Conclusion

CS1028 means you have extra pieces of a logic puzzle left over.

  1. Count Your Directives: Ensure every #endif maps back to exactly one #if.
  2. Check Scope: Ensure #else and #elif are strictly sandwiched between an opening #if and a closing #endif.
  3. Refactoring Check: If you deleted an #if statement recently, make sure you deleted its footer as well.