stride3d/stride · error · ArgumentException
The offset of the is not a multiple of 4 bytes
Error message
The offset of the {nameof(VertexElement)} is not a multiple of 4 bytes What it means
A validation guard in VertexElementValidator.Validate: it fires when a vertex element's computed byte offset is not a multiple of 4. Graphics APIs require 4-byte alignment for vertex element offsets; an element that starts at an unaligned offset would be rejected by the GPU driver, so the validator rejects the vertex declaration early with ArgumentException on the elements parameter.
Solutions
- Pad preceding elements so every offset is a multiple of 4
- Widen small elements to 4-byte formats (e.g. R16G16 to R32G32)
- Recompute offsets sequentially, rounding each up to the next multiple of 4
Example fix
// before // R16 at offset 0 (2 bytes), R32G32 at offset 2 -> misaligned // after // R32 at offset 0 (4 bytes), R32G32 at offset 4
Defensive patterns
Strategy: validation
Validate before calling
bool IsAligned(int offset) => (offset & 3) == 0;
Try / catch
try { VertexElementValidator.Validate(stride, elements); } catch (ArgumentException) { alignOffsetsTo4(); } Prevention
- Round every element offset up to the next multiple of 4
- Widen 16-bit elements to 32-bit formats to keep alignment
- Lay out elements in 4-byte units
When it happens
Trigger: Assigning offsets like 2, 6, or 10 in a vertex declaration — typically after adding a small 2-byte element and computing subsequent offsets naively.
Common situations: Packed layouts with 16-bit elements stacked at odd offsets; hand-written offsets copied from struct layouts with packing quirks.
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 's offset and size makes it extend beyond the vertex…
- The vertex stride is not a multiple of 4 bytes
- A overlaps with another element. Check the element's offset
- Cannot specify a semantic index when using the constructor…
- Could not parse semantic index from the semantic name
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/eaeccb9fc973e318.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/VertexElementValidator.cs:91
for (int elementIndex = 0; elementIndex < elements.Length; elementIndex++)
{
// Compute the offset for this element
int elementOffset = elements[elementIndex].AlignedByteOffset;
if (elementOffset == VertexElement.AppendAligned)
{
elementOffset = elementIndex == 0 ? 0 : totalOffset + elements[elementIndex - 1].Format.SizeInBytes;
}
totalOffset = elementOffset;
// Validate the element offset
int typeSize = elements[elementIndex].Format.SizeInBytes;
if (elementOffset == VertexElement.AppendAligned || (elementOffset + typeSize) > vertexStride)
{
throw new ArgumentException($"The {nameof(VertexElement)}'s offset and size makes it extend beyond the vertex stride", nameof(elements));
}
if ((elementOffset & 3) != 0)
{
throw new ArgumentException($"The offset of the {nameof(VertexElement)} is not a multiple of 4 bytes", nameof(elements));
}
// Check for duplicate semantic names and indices
for (int i = 0; i < elementIndex; i++)
{
if (elements[elementIndex].SemanticName.Equals(elements[i].SemanticName) &&
elements[elementIndex].SemanticIndex == elements[i].SemanticIndex)
{
throw new ArgumentException($"Duplicate {nameof(VertexElement)}s found with the same semantic name and index", nameof(elements));
}
}
// Check for overlap with existing elements
for (int i = elementOffset; i < (elementOffset + typeSize); i++)
{
// Check for overlap with existing elements
if (overlapCheckArray[i] >= 0)
{View on GitHub (pinned to 96fad776d2)