dotnet/wpf · error · XamlParseException
SR.MarkupExtensionDepthExceeded
Error message
SR.MarkupExtensionDepthExceeded
What it means
P_MarkupExtension guards against runaway recursion: nesting of markup extensions beyond MaxMarkupExtensionDepth throws XamlParseException(SR.MarkupExtensionDepthExceeded, depth). The guard exists to protect the parser from stack overflow on pathological or cyclic input, and can be disabled via XamlAppContextSwitches.DisableMarkupExtensionDepthGuard.
Solutions
- Flatten the markup-extension nesting into simpler property assignments
- Reduce nesting by defining intermediate resources instead of inline nested extensions
- Set XamlAppContextSwitches.DisableMarkupExtensionDepthGuard = true only for trusted input needing greater depth
- Sanitize untrusted XAML before parsing
Example fix
// before
var val = "{Binding {Binding {Binding ... /* hundreds deep */}}}";
// after
// declare intermediate resources:
<TextBlock Text="{StaticResource Inner}"/> Defensive patterns
Strategy: validation
Validate before calling
int NestingDepth(string s)
{
int depth = 0, max = 0;
foreach (char c in s ?? "")
{
if (c == '{') max = Math.Max(max, ++depth);
else if (c == '}') depth = Math.Max(0, depth - 1);
}
return max;
}
// reject if NestingDepth(input) exceeds your allowed limit Try / catch
try { nodes = parser.Parse(meString); }
catch (XamlParseException ex) when (ex.Message.Contains("depth")) { /* reject/flatten this input */ } Prevention
- Limit nesting when generating markup extensions
- Sanitize untrusted XAML before parsing
- Leave the depth guard enabled unless you fully control input
When it happens
Trigger: Parsing markup extensions nested deeper than MaxMarkupExtensionDepth (via Parse or P_Value), e.g. deeply chained '{Binding {Binding {Binding ...}}}' or malicious untrusted XAML input.
Common situations: Untrusted XAML input with intentionally deep nesting, generated code with runaway recursive markup-extension composition, buggy string builders producing nested extensions.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- ArgumentNullException(nameof(arrayType))
- ArgumentNullException(nameof(member))
- brokenRule (SR.UnexpectedToken-based parser rule error)
- IAmbientProvider
- IXamlSchemaContextProvider
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/b9a09c61e0b2f9c1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Parser/MePullParser.cs:110
{
if (_tokenizer.Token != token)
{
SetBrokenRuleString(ruleString);
return false;
}
return true;
}
////////////////////////////////
// MarkupExtension ::= '{' TYPENAME Arguments? '}'
//
private IEnumerable<XamlNode> P_MarkupExtension(Found f)
{
if (!XamlAppContextSwitches.DisableMarkupExtensionDepthGuard &&
_context.MarkupExtensionDepth >= MaxMarkupExtensionDepth)
{
throw new XamlParseException(
_tokenizer,
SR.Format(SR.MarkupExtensionDepthExceeded, MaxMarkupExtensionDepth));
}
_context.MarkupExtensionDepth++;
try
{
// MarkupExtension ::= @'{' TYPENAME Arguments? '}'
if (Expect(MeTokenType.Open, "MarkupExtension ::= @'{' Expr '}'"))
{
NextToken();
// MarkupExtension ::= '{' @TYPENAME Arguments? '}'
if (_tokenizer.Token == MeTokenType.TypeName)
{
XamlType xamlType = _tokenizer.TokenType;
yield return Logic_StartElement(xamlType, _tokenizer.Namespace);View on GitHub (pinned to 81131a70a4)