QuestPDF/QuestPDF · error · DocumentComposeException

The Layers component needs to have exactly one primary layer

Error message

The Layers component needs to have exactly one primary layer. It has {primaryLayers}.

What it means

The Layers component's Validate() also throws when more than one primary layer exists, because multiple primary layers would conflict over which content drives paging and target length. The message interpolates the actual count. Exactly one PrimaryLayer() call is permitted per Layers handler.

Source

Thrown at src/dotnet/library/QuestPDF/Fluent/LayerExtensions.cs:58

        public IContainer Layer() => Layer(false);
        
        /// <summary>
        /// Sets the primary content for the container. 
        /// </summary>
        /// <remarks>
        /// Exactly one primary layer should be defined.
        /// </remarks>
        public IContainer PrimaryLayer() => Layer(true);

        internal void Validate()
        {
            var primaryLayers = Layers.Children.Count(x => x.IsPrimary);

            if (primaryLayers == 0)
                throw new DocumentComposeException("The Layers component needs to have exactly one primary layer. It has none.");
            
            if (primaryLayers != 1)
                throw new DocumentComposeException($"The Layers component needs to have exactly one primary layer. It has {primaryLayers}.");
        }
    }
    
    public static class LayerExtensions
    {
        /// <summary>
        /// <para>Adds content either underneath (as a background) or on top of (as a watermark) the main content.</para>
        /// <para>The main layer supports paging, can span multiple pages, and determines the container's target length.</para>
        /// <para>Additional layers can also span multiple pages and are repeated on each one.</para>
        /// <a href="https://www.questpdf.com/api-reference/layers.html">Learn more</a>
        /// </summary>
        /// <param name="handler">Handler for defining content of the container, including exactly one primary layer and any additional layers in a specified order.</param>
        public static void Layers(this IContainer element, Action<LayersDescriptor> handler)
        {
            var descriptor = new LayersDescriptor();

            handler(descriptor);
            descriptor.Validate();

View on GitHub (pinned to 43ab125596)

Solutions

  1. Keep exactly one desc.PrimaryLayer() in the handler; convert extras to desc.Layer() (secondary/background/watermark).
  2. Audit the handler for all PrimaryLayer() calls and retain a single one.
  3. Decide which content is the main flow and nest the rest as secondary layers.

Example fix

// before
container.Layers(desc => {
    desc.PrimaryLayer().Text("a");
    desc.PrimaryLayer().Text("b"); // count=2 -> throws
});

// after
container.Layers(desc => {
    desc.PrimaryLayer().Text("a");
    desc.Layer().Text("b"); // secondary layer
});
Defensive patterns

Strategy: validation

Validate before calling

container.Layers(desc => {
    desc.PrimaryLayer().Element(mainBody); // single primary
    foreach (var extra in extras)
        desc.Layer().Element(extra);        // secondary layers, not primary
});

Type guard

// Guard at authoring time: search the Layers handler for 'PrimaryLayer' and ensure count == 1.
// Combine all main content into the single primary layer; use desc.Layer() for the rest.

Try / catch

try { /* generate document */ }
catch (DocumentComposeException ex) when (ex.Message.Contains("exactly one primary layer")) {
    // Remove duplicate PrimaryLayer() calls; convert extras to desc.Layer().
    throw;
}

Prevention

When it happens

Trigger: Calling desc.PrimaryLayer() two or more times within a single .Layers(handler) block.

Common situations: Copy-paste that duplicated PrimaryLayer(); merging two layout fragments that each declared their own primary; misunderstanding that Layer(true)/PrimaryLayer must be unique.

Related errors


AI-assisted analysis of QuestPDF/QuestPDF@43ab125596 (2026-08-13). Data as JSON: /api/errors/24b1b72739f67c2c. Report an issue: GitHub.