stride3d/stride · error · ArgumentException
Offsets are only supported for Textures declared with
Error message
Offsets are only supported for Textures declared with {nameof(GraphicsResourceUsage)}.{nameof(GraphicsResourceUsage.Default)} What it means
SetData supports a byte offset only when the buffer's usage is GraphicsResourceUsage.Default, because then it uses UpdateSubresource with a destination region. For other usages (Dynamic/Staging) the CPU-map path has no subresource region support, so any offsetInBytes > 0 throws ArgumentException. The message text literally leaks the {nameof(...)} placeholders unexpanded.
Solutions
- Use GraphicsResourceUsage.Default for the buffer when you need offset writes.
- Set offsetInBytes to 0 and upload the full data instead of a partial offset write.
- For partial updates of dynamic buffers, write the whole slab and use a constant-buffer offset in the shader, or create the buffer with Default usage.
Example fix
// before dynamicBuffer.SetData(cmd, newData, offsetInBytes: 64); // throws // after defaultBuffer = Buffer.New<float>(device, count, BufferFlags.ConstantBuffer, GraphicsResourceUsage.Default); defaultBuffer.SetData(cmd, newData, offsetInBytes: 64);
Defensive patterns
Strategy: validation
Validate before calling
if (offsetInBytes > 0 && buffer.Description.Usage != GraphicsResourceUsage.Default)
throw new InvalidOperationException("Offset writes need Default usage"); Type guard
bool SupportsOffsetWrite(Buffer b) => b.Description.Usage == GraphicsResourceUsage.Default;
Try / catch
try { buffer.SetData(cmd, data, offsetInBytes); }
catch (ArgumentException ex) when (ex.Message.Contains("Offsets are only supported"))
{
buffer.SetData(cmd, data, 0); // fall back to full write
} Prevention
- Use Default usage for offset writes.
- Default offsetInBytes to 0 for Dynamic/Staging buffers.
- Prefer writing whole slabs for dynamic buffers.
When it happens
Trigger: Calling buffer.SetData(commandList, data, offsetInBytes: N) with N > 0 on a buffer whose Description.Usage is Dynamic or Staging (e.g. a Dynamic constant or vertex buffer).
Common situations: Partially updating sub-ranges of a dynamic buffer with an offset; porting XNA/MonoGame code that used UpdateSubresource offsets onto a Staging or Dynamic buffer.
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
- The length of the destination data buffer is larger than…
- The length of the source data to upload is larger than the…
- Element size must be set to sizeof(short) = 2 or…
- size needs to be a multiple of constant buffer alignment
- Element size cannot be less or equal 0 for structured buffer
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/16e6fa119c101c8f.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/Buffer.cs:514
// If the Buffer is declared as Default usage, we can only use UpdateSubresource, which is not optimal but better than nothing
if (Description.Usage == GraphicsResourceUsage.Default)
{
// Set up the dest region inside the Buffer
if (Description.BufferFlags.HasFlag(BufferFlags.ConstantBuffer))
{
commandList.UpdateSubResource(this, subResourceIndex: 0, fromDataAsBytes);
}
else
{
var destRegion = new ResourceRegion(left: offsetInBytes, top: 0, front: 0, right: offsetInBytes + fromDataSizeInBytes, bottom: 1, back: 1);
commandList.UpdateSubResource(this, subResourceIndex: 0, fromDataAsBytes, destRegion);
}
}
else
{
if (offsetInBytes > 0)
throw new ArgumentException("Offsets are only supported for Textures declared with {nameof(GraphicsResourceUsage)}.{nameof(GraphicsResourceUsage.Default)}", nameof(offsetInBytes));
// Map the Buffer to CPU-writable memory
var mappedResource = commandList.MapSubResource(this, subResourceIndex: 0, Usage == GraphicsResourceUsage.Staging ? MapMode.Write : MapMode.WriteDiscard);
var toData = new Span<TData>((void*) mappedResource.DataBox.DataPointer, fromData.Length);
fromData.CopyTo(toData);
//Utilities.CopyWithAlignmentFallback((void*)mappedResource.DataBox.DataPointer, pointer, (uint)sizeInBytes);
commandList.UnmapSubResource(mappedResource);
}
}
#endregion
/// <summary>
/// Creates a new <see cref="Buffer"/>.
/// </summary>
/// <param name="device">The <see cref="GraphicsDevice"/>.</param>
/// <param name="description">The description of the Buffer.</param>
/// <param name="viewFormat">View on GitHub (pinned to 96fad776d2)