stride3d/stride · error · InvalidOperationException
Invalid Width/Height/Depth/ArraySize for Image 3D
Error message
Invalid Width/Height/Depth/ArraySize for Image 3D
What it means
For Texture3D images, Initialize requires Width > 0, Height > 0, Depth > 0, and ArraySize == 1. Volumetric textures must be truly 3-dimensional, and 3D images cannot be arrayed (ArraySize must be exactly 1).
Solutions
- Set ArraySize = 1 for Texture3D images.
- Ensure Width, Height, and Depth are all > 0.
- If you need an array of 2D slices, use Texture2D with ArraySize > 1 instead.
- Validate the source file's depth field before constructing the description.
Example fix
// before
var desc = new ImageDescription { Dimension = TextureDimension.Texture3D, Width = 64, Height = 64, Depth = 64, ArraySize = 4 };
// after
var desc = new ImageDescription { Dimension = TextureDimension.Texture3D, Width = 64, Height = 64, Depth = 64, ArraySize = 1 }; Defensive patterns
Strategy: validation
Validate before calling
if (desc.Dimension == TextureDimension.Texture3D &&
(desc.Width <= 0 || desc.Height <= 0 || desc.Depth <= 0 || desc.ArraySize != 1))
throw new ArgumentException("Texture3D requires Width/Height/Depth>0 and ArraySize=1."); Type guard
null
Try / catch
try { img = Image.New(desc, ptr); }
catch (InvalidOperationException ex) when (ex.Message.Contains("for Image 3D"))
{
desc.ArraySize = 1;
img = Image.New(desc, ptr);
} Prevention
- Always reset ArraySize to 1 when converting a 2D-array description to 3D.
- Validate volumetric file headers (depth > 0) before constructing descriptions.
- Use a dedicated New3D factory to keep invariants in one place.
- Unit-test each dimension's description builder.
When it happens
Trigger: Creating an Image with Dimension = TextureDimension.Texture3D where any of Width/Height/Depth is <= 0, or where ArraySize was left > 1 or left at a non-1 value copied from a 2D array description.
Common situations: Loading volumetric data where the depth read from the file header is 0; cloning a 2D texture-array description and only changing Dimension to Texture3D (keeping ArraySize = 4); default-initialized descriptions with zeroed dimensions.
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
- Unsupported DXGI Format
- Cannot specify custom stride with mipmaps
- Invalid Width/Height/Depth/ArraySize for Image 1D
- Invalid Width/Height/Depth/ArraySize for Image 2D
- TextureCube must have an arraysize = 6
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/6cf4b153f1be7760.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Foundation/Graphics/Image.cs:800
case TextureDimension.Texture2D:
case TextureDimension.TextureCube:
if (description.Width <= 0 || description.Height <= 0 || description.Depth != 1 || description.ArraySize == 0)
throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 2D");
if (description.Dimension == TextureDimension.TextureCube)
{
if ((description.ArraySize % 6) != 0)
throw new InvalidOperationException("TextureCube must have an arraysize = 6");
}
// Check that miplevels are fine
description.MipLevels = CalculateMipLevels(description.Width, description.Height, description.MipLevels);
break;
case TextureDimension.Texture3D:
if (description.Width <= 0 || description.Height <= 0 || description.Depth <= 0 || description.ArraySize != 1)
throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 3D");
// Check that miplevels are fine
description.MipLevels = CalculateMipLevels(description.Width, description.Height, description.Depth, description.MipLevels);
break;
}
// Calculate mipmaps
mipMapToZIndex = CalculateImageArray(description, pitchFlags, rowStride, out var pixelBufferCount, out totalSizeInBytes);
mipmapDescriptions = CalculateMipMapDescription(description);
zBufferCountPerArraySlice = mipMapToZIndex[^1];
// Allocate all pixel buffers
PixelBuffers = new PixelBuffer[pixelBufferCount];
pixelBufferArray = new PixelBufferArray(this);
// Setup all pointers
// only release buffer that is not pinned and is asked to be disposed.
this.bufferIsDisposable = !handle.HasValue && bufferIsDisposable;View on GitHub (pinned to 96fad776d2)