stride3d/stride · error · InvalidOperationException

NoStencilBufferForDepthFormat (formatted with ViewFormat)

Error message

NoStencilBufferForDepthFormat (formatted with ViewFormat)

What it means

Thrown in CommandList.Clear on D3D12 when DepthStencilClearOptions.Stencil is requested but the bound depth-stencil buffer has no stencil component (HasStencil == false). The library throws InvalidOperationException, formatting FrameworkResources.NoStencilBufferForDepthFormat with the buffer's ViewFormat, because there is no stencil plane to clear.

Solutions

  1. Remove DepthStencilClearOptions.Stencil from the clear options, clearing depth only.
  2. Recreate the depth-stencil buffer with a packed depth-stencil format (D24_UNorm_S8_UInt or D32_Float_S8X24_UInt).
  3. Guard the call with a check of depthStencilBuffer.HasStencil before requesting a stencil clear.

Example fix

// before
commandList.Clear(depthBuffer, DepthStencilClearOptions.Depth | DepthStencilClearOptions.Stencil);
// after
var options = depthBuffer.HasStencil
    ? DepthStencilClearOptions.Depth | DepthStencilClearOptions.Stencil
    : DepthStencilClearOptions.Depth;
commandList.Clear(depthBuffer, options);
Defensive patterns

Strategy: type-guard

Validate before calling

if (options.HasFlag(DepthStencilClearOptions.Stencil) && !depthStencilBuffer.HasStencil)
    options &= ~DepthStencilClearOptions.Stencil;

Type guard

static bool SupportsStencilClear(Texture depthBuffer, DepthStencilClearOptions options) => !options.HasFlag(DepthStencilClearOptions.Stencil) || depthBuffer.HasStencil;

Try / catch

try { commandList.Clear(depthBuffer, options); }
catch (InvalidOperationException ex) when (ex.Message.Contains("stencil")) { commandList.Clear(depthBuffer, options & ~DepthStencilClearOptions.Stencil); }

Prevention

When it happens

Trigger: Calling commandList.Clear(depthStencilBuffer, DepthStencilClearOptions.Depth | DepthStencilClearOptions.Stencil, ...) (or just Stencil) where depthStencilBuffer.ViewFormat is stencil-less, e.g. D16_UNorm or D32_Float instead of D24_UNorm_S8_UInt / D32_Float_S8X24_UInt.

Common situations: A shared clear helper always passing Stencil, a camera/graphics-compositor configured with a depth-only format while stencil clears remain enabled, or switching the depth format to D32_Float for precision without updating clear options.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/5bfefab009fe4c2b. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs:1172

        /// <param name="options">
        ///   A combination of <see cref="DepthStencilClearOptions"/> flags identifying what parts of the Depth-Stencil Buffer to clear.
        /// </param>
        /// <param name="depth">The depth value to use for clearing the Depth Buffer.</param>
        /// <param name="stencil">The stencil value to use for clearing the Stencil Buffer.</param>
        /// <exception cref="ArgumentNullException"><paramref name="depthStencilBuffer"/> is <see langword="null"/>.</exception>
        /// <exception cref="InvalidOperationException">Cannot clear a Stencil Buffer without a Stencil Buffer format.</exception>
        public void Clear(Texture depthStencilBuffer, DepthStencilClearOptions options, float depth = 1, byte stencil = 0)
        {
            ArgumentNullException.ThrowIfNull(depthStencilBuffer);

            ResourceBarrierTransition(depthStencilBuffer, BarrierLayout.DepthStencilWrite);
            FlushResourceBarriers();

            // Check that the Depth-Stencil Buffer has a Stencil if Clear Stencil is requested
            if (options.HasFlag(DepthStencilClearOptions.Stencil))
            {
                if (!depthStencilBuffer.HasStencil)
                    throw new InvalidOperationException(string.Format(FrameworkResources.NoStencilBufferForDepthFormat, depthStencilBuffer.ViewFormat));
            }

            scoped ref SilkBox2I nullRect = ref NullRef<SilkBox2I>();

            currentCommandList.NativeCommandList.ClearDepthStencilView(depthStencilBuffer.NativeDepthStencilView,
                                                                       (ClearFlags) options, depth, stencil,
                                                                       NumRects: 0, in nullRect);
            RecordDebugCounter(DebugCounterKind.Clear);
        }

        /// <summary>
        ///   Clears the specified Render Target.
        /// </summary>
        /// <param name="renderTarget">The Render Target to clear.</param>
        /// <param name="color">The color to use to clear the Render Target.</param>
        /// <exception cref="ArgumentNullException"><paramref name="renderTarget"/> is <see langword="null"/>.</exception>
        public void Clear(Texture renderTarget, Color4 color)
        {

View on GitHub (pinned to 96fad776d2)