MonoGame/MonoGame · error · ArgumentOutOfRangeException

numVertices

Error message

numVertices

What it means

Thrown by DrawUserIndexedPrimitives<T> when numVertices is <= 0 or greater than vertexData.Length. numVertices declares how many vertices (from vertexOffset) are available for indexing; it must be a positive count that fits within the array. This check runs after the vertexOffset range check.

Source

Thrown at MonoGame.Framework/Graphics/GraphicsDevice.cs:1396

        /// <param name="numVertices">The number of vertices to draw.</param>
        /// <param name="indexData">The index data.</param>
        /// <param name="vertexDeclaration">The layout of the vertices.</param>
        /// <remarks>All indices in the vertex buffer are interpreted relative to the specified <paramref name="vertexOffset"/>.
        /// For example a value of zero in the array of indices points to the vertex at index <paramref name="vertexOffset"/>
        /// in the array of vertices.</remarks>
        public void DrawUserIndexedPrimitives<T>(PrimitiveType primitiveType, T[] vertexData, int vertexOffset, int numVertices, short[] indexData, int indexOffset, int primitiveCount, VertexDeclaration vertexDeclaration) where T : struct
        {
            // These parameter checks are a duplicate of the checks in the int[] overload of DrawUserIndexedPrimitives.
            // Inlined here for efficiency.

            if (vertexData == null || vertexData.Length == 0)
                throw new ArgumentNullException("vertexData");

            if (vertexOffset < 0 || vertexOffset >= vertexData.Length)
                throw new ArgumentOutOfRangeException("vertexOffset");

            if (numVertices <= 0 || numVertices > vertexData.Length)
                throw new ArgumentOutOfRangeException("numVertices");

            if (vertexOffset + numVertices > vertexData.Length)
                throw new ArgumentOutOfRangeException("numVertices");

            if (indexData == null || indexData.Length == 0)
                throw new ArgumentNullException("indexData");

            if (indexOffset < 0 || indexOffset >= indexData.Length)
                throw new ArgumentOutOfRangeException("indexOffset");

            if (primitiveCount <= 0)
                throw new ArgumentOutOfRangeException("primitiveCount");

            if (indexOffset + GetElementCountArray(primitiveType, primitiveCount) > indexData.Length)
                throw new ArgumentOutOfRangeException("primitiveCount");

            if (vertexDeclaration == null)
                throw new ArgumentNullException("vertexDeclaration");

View on GitHub (pinned to 1d71bbd0ff)

Solutions

  1. Set numVertices to the live count of vertices used by the indices: usually vertexData.Length for a full-array draw, or a tracked active count for a subrange.
  2. Ensure 0 < numVertices <= vertexData.Length, and additionally vertexOffset + numVertices <= vertexData.Length.
  3. Recompute numVertices whenever the vertex array or the active range changes.

Example fix

// before
_graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, _verts, 0, _cachedVertCount, _indices, 0, primCount, decl);

// after
int numVertices = Math.Min(_cachedVertCount, _verts.Length);
if (numVertices > 0)
    _graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, _verts, 0, numVertices, _indices, 0, primCount, decl);
Defensive patterns

Strategy: validation

Validate before calling

int numVertices = Math.Clamp(requestedNumVertices, 1, vertexData.Length);
if (numVertices <= 0) return;

Type guard

static bool IsValidNumVertices<T>(T[] vertexData, int numVertices) where T : struct
    => vertexData != null && numVertices > 0 && numVertices <= vertexData.Length;

Try / catch

try { _graphicsDevice.DrawUserIndexedPrimitives(pt, vertexData, vertexOffset, numVertices, indexData, indexOffset, primCount, decl); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "numVertices")
{
    // numVertices <= 0 or > vertexData.Length; recompute.
}

Prevention

When it happens

Trigger: Calling DrawUserIndexedPrimitives with numVertices <= 0, or numVertices > vertexData.Length.

Common situations: Passing vertexData.Length as numVertices after the array shrank (stale count). Passing 0 because the active vertex count was not yet computed. Confusing numVertices (a count) with the last vertex index. A sub-range draw where numVertices was sized for the whole buffer but vertexOffset > 0.

Related errors


AI-assisted analysis of MonoGame/MonoGame@1d71bbd0ff (2026-08-13). Data as JSON: /api/errors/3584424cd7bb2614. Report an issue: GitHub.