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

  1. Flatten the markup-extension nesting into simpler property assignments
  2. Reduce nesting by defining intermediate resources instead of inline nested extensions
  3. Set XamlAppContextSwitches.DisableMarkupExtensionDepthGuard = true only for trusted input needing greater depth
  4. 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

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


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)