Skip to main content

How to Resolve Error "CS0061: Inconsistent accessibility: base interface 'interface 1' is less accessible than interface 'interface 2'" in C#

The Compiler Error CS0061 is an Inheritance visibility error specifically regarding Interfaces. The message reads: "Inconsistent accessibility: base interface 'IBase' is less accessible than interface 'IDerived'".

This error enforces a logical rule in the C# type system: A public contract cannot depend on a secret contract. If you define a public interface (visible to the world), it cannot inherit from an internal or private interface. Because the derived interface includes all members of the base interface, exposing the child implies exposing the parent. If the parent is hidden, the contract is invalid.

This guide explains how to align the visibility of your interface hierarchy to resolve this error.

Understanding Interface Inheritance Rules

In C#, an interface can inherit from other interfaces.

  • If IDerived is public, external code can implement it or use it.
  • Since IDerived inherits from IBase, anyone using IDerived is also implicitly using IBase.
  • If IBase is internal, external code is not allowed to know it exists.

The compiler blocks this because you are trying to expose IBase functionality through IDerived to people who don't have permission to see IBase.

The Rule: A base interface must be at least as accessible as the interface inheriting from it.

Scenario 1: Public Child, Internal Base (The Default Trap)

This is the most frequent cause. In C#, if you declare an interface without an access modifier (e.g., interface IBase), it defaults to internal. If you then create a derived interface explicitly marked as public, you trigger CS0061.

Example of error:

// No modifier = 'internal' (visible only inside this project)
interface ICoreFunctions
{
void Save();
}

// ⛔️ Error CS0061: Inconsistent accessibility:
// base interface 'ICoreFunctions' is less accessible than interface 'IAdvancedFunctions'.
// 'IAdvancedFunctions' is PUBLIC (Open to the world).
// 'ICoreFunctions' is INTERNAL (Hidden).
public interface IAdvancedFunctions : ICoreFunctions
{
void Delete();
}

Solution 1: Make the Base Interface Public

If the interface hierarchy is intended to be part of your public API (i.e., you want users to implement or use the full contract), you must make the Base interface public.

Solution: add the public keyword to the base interface.

// ✅ Correct: Explicitly mark the base as public
public interface ICoreFunctions
{
void Save();
}

// Now valid because both interfaces are public.
public interface IAdvancedFunctions : ICoreFunctions
{
void Delete();
}

Solution 2: Restrict the Derived Interface

If the Base interface is an implementation detail that should remain hidden (internal), then the Derived interface typically shouldn't be public either. You should restrict the Derived interface to match the Base interface's visibility.

Solution: change the derived interface to internal.

internal interface ICoreFunctions // Remains internal
{
void Save();
}

// ✅ Correct: The derived interface is now 'internal'.
// It is no longer more visible than its parent.
internal interface IAdvancedFunctions : ICoreFunctions
{
void Delete();
}
note

Why can't I hide the base? Imagine IAdvancedFunctions was public. A user in another DLL implements it. They would be forced to implement Save() (from the base), but they wouldn't have access to the definition of Save() because ICoreFunctions is hidden. This is why the compiler forbids it.

Conclusion

CS0061 ensures the integrity of your API contracts.

  1. Check the Child: Is the derived interface public?
  2. Check the Parent: Is the base interface internal (default) or private?
  3. Align Them:
    • Make Base Public: If the interfaces are for public use.
    • Make Child Internal: If the interfaces are for internal project logic.