How to Resolve Error "CS0592: Attribute 'attribute' is not valid on this declaration type" in C#
The Compiler Error CS0592 is a usage restriction error regarding Attributes. The message reads: "Attribute 'AttributeName' is not valid on this declaration type. It is valid on 'ValidType' declarations only."
In C#, Attributes are not "one size fits all." When an Attribute class is defined, the developer specifies exactly where it can be used (e.g., only on Methods, only on Classes, or only on Properties) using the [AttributeUsage] meta-attribute. If you attempt to place an attribute on a code element that it was not designed to decorate, the compiler raises CS0592.
This guide explains how AttributeUsage works and how to resolve this mismatch.
Understanding Attribute Targets
Every Attribute class is decorated with [AttributeUsage(AttributeTargets.X)]. The AttributeTargets enum defines the valid locations:
AttributeTargets.ClassAttributeTargets.MethodAttributeTargets.PropertyAttributeTargets.FieldAttributeTargets.All(Valid everywhere)
For example, the [Serializable] attribute is defined with AttributeTargets.Class | AttributeTargets.Struct. If you try to put [Serializable] on a Method, the compiler blocks it because serialization applies to data structures, not logic.
Scenario: Misplaced Attributes
This error commonly occurs when using custom attributes for logging or validation and accidentally placing them on the Class instead of a Method, or vice versa.
Attribute Definition
Here, we define a custom attribute that is strictly intended for Methods.
using System;
namespace MyProject
{
// This attribute allows usage ONLY on methods.
[AttributeUsage(AttributeTargets.Method)]
public class LogExecutionAttribute : Attribute
{
}
}
Example of error
Attempting to apply this method-specific attribute to a Class.
namespace MyProject
{
// ⛔️ Error CS0592: Attribute 'LogExecution' is not valid on this declaration type.
// It is valid on 'method' declarations only.
[LogExecution]
public class DataProcessor
{
public void Process()
{
Console.WriteLine("Processing...");
}
}
}
Solution 1: Move the Attribute (Correct Usage)
If you are using a standard .NET attribute (like [DllImport], [Serializable], or ASP.NET attributes) or a third-party library attribute, you cannot change its definition. You must move the attribute to a valid location.
Solution: apply the attribute to the element it supports (in this case, a method).
namespace MyProject
{
public class DataProcessor
{
// ✅ Correct: The attribute is applied to a method, which matches its definition.
[LogExecution]
public void Process()
{
Console.WriteLine("Processing...");
}
}
}
How to check valid targets:
Right-click the attribute name in Visual Studio and select Go To Definition. Look for the [AttributeUsage(...)] line above the class definition to see where it is allowed.
Solution 2: Update the Attribute Definition
If you are the author of the custom attribute and you want it to be supported on other elements (e.g., you want to allow logging on an entire class to imply logging for all its methods), you can modify the definition.
Solution: update the AttributeUsage to include the new target using the bitwise OR operator |.
using System;
namespace MyProject
{
// ✅ Correct: Now supports both Methods AND Classes
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class LogExecutionAttribute : Attribute
{
}
}
// Now this is valid:
[LogExecution]
public class DataProcessor
{
/* ... */
}
Conclusion
CS0592 ensures that attributes are only used where they make sense.
- Check the Attribute: Look at the definition of the attribute you are using.
- Move It: If it's a system attribute (e.g.,
[field: NonSerialized]), ensure you placed it on the right part of the code. - Modify It: If it's your own attribute, expand the
[AttributeUsage]flags to support the new location.