stride3d/stride · error · ArgumentException

The length of the destination data buffer is larger than…

Error message

The length of the destination data buffer is larger than the size of the Buffer

What it means

Buffer.GetData validates that the destination Span<TData>'s size in bytes does not exceed the GPU buffer's SizeInBytes before copying from a staging resource. Throwing ArgumentException here prevents reading past the end of the buffer into unrelated GPU-mapped memory.

Solutions

  1. Size the destination Span so its byte length is <= buffer.SizeInBytes.
  2. Check buffer.SizeInBytes before the call and clamp/slice the span accordingly.
  3. Recreate the buffer with a larger SizeInBytes if the data legitimately grew.
  4. Verify the element type TData matches the type the buffer was created with.

Example fix

// before
var data = new float[buffer.SizeInBytes]; // 4x too large in elements? actually larger than buffer
buffer.GetData(cmd, staging, data);
// after
var data = new float[buffer.SizeInBytes / sizeof(float)];
buffer.GetData(cmd, staging, data.AsSpan());
Defensive patterns

Strategy: validation

Validate before calling

if (toData.Length * sizeof(TData) > buffer.SizeInBytes)
    throw new ArgumentException("Destination span too large for buffer");

Type guard

bool CanReadInto<TData>(Buffer b, Span<TData> dst) where TData : unmanaged => dst.Length * sizeof(TData) <= b.SizeInBytes;

Try / catch

try { buffer.GetData(cmd, staging, span); }
catch (ArgumentException ex) when (ex.Message.Contains("destination data buffer"))
{
    span = span.Slice(0, buffer.SizeInBytes / sizeof(TData));
    buffer.GetData(cmd, staging, span);
}

Prevention

When it happens

Trigger: Calling buffer.GetData(commandList, stagingBuffer, span) where span.Length * sizeof(TData) > buffer.SizeInBytes, e.g. a Span<float> of 1024 elements read from a 2KB buffer or a larger element type than was uploaded.

Common situations: Buffer resized after the read code was written; reading a vertex buffer into a struct array with bigger stride; copying a partial buffer into a span sized for a larger buffer.

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 stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/2045b38c70ff9425. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Graphics/Buffer.cs:397

        /// <summary>
        ///   Copies the content of the Buffer from GPU memory to a CPU memory pointer using a specific staging resource.
        /// </summary>
        /// <typeparam name="TData">The type of the data to read from the Buffer.</typeparam>
        /// <param name="commandList">The <see cref="CommandList"/>.</param>
        /// <param name="stagingBuffer">The staging buffer used to transfer the data from GPU memory.</param>
        /// <param name="toData">To destination span where the read data will be written.</param>
        /// <exception cref="ArgumentException">
        ///   The length of the destination data buffer (<paramref name="toData"/>) is larger than the size of the Buffer.
        /// </exception>
        /// <remarks>
        ///   This method only works when called from the main thread that is accessing the main <see cref="GraphicsDevice"/>.
        /// </remarks>
        public unsafe void GetData<TData>(CommandList commandList, Buffer stagingBuffer, Span<TData> toData) where TData : unmanaged
        {
            // Check destination buffer has valid size
            int toDataSizeInBytes = toData.Length * sizeof(TData);
            if (toDataSizeInBytes > SizeInBytes)
                throw new ArgumentException("The length of the destination data buffer is larger than the size of the Buffer");

            // Copy the Buffer to a staging resource
            if (!ReferenceEquals(this, stagingBuffer))
                commandList.Copy(this, stagingBuffer);

            // Map the staging resource to CPU-readable memory
            var mappedResource = commandList.MapSubResource(stagingBuffer, subResourceIndex: 0, MapMode.Read);
            var fromData = new ReadOnlySpan<TData>((void*) mappedResource.DataBox.DataPointer, toData.Length);
            fromData.CopyTo(toData);
            //Utilities.CopyWithAlignmentFallback(pointer, (void*)mappedResource.DataBox.DataPointer, (uint)toDataInBytes);
            commandList.UnmapSubResource(mappedResource);
        }

        #endregion

        #region SetData: Writing data into the Buffer

        /// <summary>

View on GitHub (pinned to 96fad776d2)