dotnet/maui · error · BuildException
XC0066
XC0066
Error message
Invalid Xaml "Protected Xmlns {xmlNamespace}. Can't add assembly {assemblyName}." What it means
Raised when an assembly tries to register itself into one of the protected XML namespaces (the MAUI uri or the XAML 2009 uri) via a XmlnsDefinitionAttribute, but its assembly name does not begin with Microsoft/System/mscorlib. Those namespaces are reserved for the framework, so the build task rejects the registration as invalid XAML.
Source
Thrown at src/Controls/src/Build.Tasks/XmlTypeExtensions.cs:62
xmlnsDefinitions.Add(attribute);
}
}
return xmlnsDefinitions;
}
static void ValidateProtectedXmlns(string xmlNamespace, string assemblyName)
{
//maui, and x: xmlns are protected
if (xmlNamespace != XamlParser.MauiUri && xmlNamespace != XamlParser.X2009Uri)
return;
//we know thos assemblies, they are fine in maui or x xmlns
if (assemblyName.StartsWith("Microsoft", StringComparison.OrdinalIgnoreCase)
|| assemblyName.StartsWith("System", StringComparison.OrdinalIgnoreCase)
|| assemblyName.StartsWith("mscorlib", StringComparison.OrdinalIgnoreCase))
return;
throw new BuildException(BuildExceptionCode.InvalidXaml, null, null,
$"Protected Xmlns {xmlNamespace}. Can't add assembly {assemblyName}.");
}
static void GatherXmlnsDefinitionAttributes(List<XmlnsDefinitionAttribute> xmlnsDefinitions, AssemblyDefinition asmDef, AssemblyDefinition currentAssembly)
{
foreach (var ca in asmDef.CustomAttributes)
{
if (ca.AttributeType.FullName == _xmlnsDefinitionName)
{
var attr = GetXmlnsDefinition(ca, asmDef);
//only add globalxmlns definition from the current assembly
if (attr.XmlNamespace == XamlParser.MauiGlobalUri
&& asmDef != currentAssembly)
continue;
ValidateProtectedXmlns(attr.XmlNamespace, attr.AssemblyName);
xmlnsDefinitions.Add(attr);
}
}View on GitHub (pinned to f377ff1c5e)
Solutions
- Change the XmlnsDefinition attribute to use your own custom uri, e.g. 'http://mycompany.com/schemas/mylib'.
- If you only want a clr-namespace shortcut, register under an unreserved uri and reference the clr-namespace directly in XAML.
- Remove the XmlnsDefinition attribute entirely if you do not need a custom xmlns prefix for your controls.
Example fix
// before
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "MyLib.Controls")]
// after
[assembly: XmlnsDefinition("http://mycompany.com/schemas/mylib", "MyLib.Controls")] Defensive patterns
Strategy: validation
Validate before calling
// Assembly-level guard: never register a third-party assembly into a reserved xmlns.
static readonly HashSet<string> Reserved = new() { XamlParser.MauiUri, XamlParser.X2009Uri };
static string SafeXmlns(string desired, string assemblyName)
=> Reserved.Contains(desired) && !assemblyName.StartsWith("Microsoft", StringComparison.OrdinalIgnoreCase)
? $"http://{assemblyName.ToLowerInvariant()}.local/schemas"
: desired; Prevention
- Use your own company/product uri for XmlnsDefinition, never the MAUI or XAML 2009 uri.
- Code-review any new [assembly: XmlnsDefinition(...)] for a reserved namespace.
- Document your library's custom xmlns in its README so consumers use the right prefix.
When it happens
Trigger: ValidateProtectedXmlns is called with xmlNamespace equal to XamlParser.MauiUri or XamlParser.X2009Uri and an assemblyName that does not StartsWith Microsoft/System/mscorlib (case-insensitive), reaching the final throw.
Common situations: A third-party library copies a Maui sample assembly attribute and reuses 'http://schemas.microsoft.com/dotnet/2021/maui' as its XmlnsDefinition; a library targets the XAML 2009 namespace intentionally; a generated assembly accidentally emits the reserved uri.
Related errors
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/a9c492e587ae5d2b.
Report an issue: GitHub.