{"record":{"id":"3a80d9cf0c86c391","repo":"stride3d/stride","slug":"invalid-stride-rowstride-value-can-t-be-lower-than-actual","errorCode":null,"errorMessage":"Invalid stride [{rowStride}]. Value can't be lower than actual stride [{rowPitch}]","messagePattern":"Invalid stride \\[(.+?)\\]\\. Value can't be lower than actual stride \\[(.+?)\\]","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Foundation/Graphics/Image.cs","lineNumber":1027,"sourceCode":"            bufferCount = 0;\n\n            var mipmapToZIndex = new List<int>();\n\n            for (int j = 0; j < imageDesc.ArraySize; j++)\n            {\n                int w = imageDesc.Width;\n                int h = imageDesc.Height;\n                int d = imageDesc.Depth;\n\n                for (int i = 0; i < imageDesc.MipLevels; i++)\n                {\n                    ComputePitch(imageDesc.Format, w, h, out var rowPitch, out var slicePitch, out var widthPacked, out var heightPacked, pitchFlags);\n\n                    if (rowStride > 0)\n                    {\n                        // Check that stride is ok\n                        if (rowStride < rowPitch)\n                            throw new InvalidOperationException($\"Invalid stride [{rowStride}]. Value can't be lower than actual stride [{rowPitch}]\");\n\n                        if (widthPacked != w || heightPacked != h)\n                            throw new InvalidOperationException(\"Custom strides is not supported with packed PixelFormats\");\n\n                        // Recalculate slice pitch\n                        slicePitch = rowStride * h;\n                    }\n\n                    // Store the number of z-slicec per miplevels\n                    if (j == 0)\n                        mipmapToZIndex.Add(bufferCount);\n\n                    // Keep a trace of indices for the 1st array size, for each mip levels\n                    pixelSizeInBytes += d * slicePitch;\n                    bufferCount += d;\n\n                    if (h > 1)\n                        h >>= 1;","sourceCodeStart":1009,"sourceCodeEnd":1045,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Foundation/Graphics/Image.cs#L1009-L1045","documentation":"When setting up a per-pixel-buffer view (PixelBuffer) with a user-supplied rowStride, the stride must be at least the naturally computed row pitch for the format and width. A smaller stride would make rows overlap/corrupt data, so Initialize/TextureData setup throws. The rowPitch is computed by ComputePitch from the pixel format and width.","triggerScenarios":"Passing a rowStride smaller than ComputePitch's rowPitch for the given format/width — e.g. stride 512 for a 256-wide R8G8B8A8_UNorm image (which needs 1024 bytes per row).","commonSituations":"Confusing row stride in bytes with pixel count; wrapping a tightly packed buffer with a stride copied from a smaller mip level; unit mistakes (stride in pixels vs bytes).","solutions":["Pass rowStride >= rowPitch (rowPitch = width * bytes-per-pixel for unpacked formats).","Pass rowStride = 0 to let Stride compute the tight pitch automatically.","Recompute the stride with the same formula Stride uses (Image.ComputePitch) for the format and width.","Check whether you accidentally passed the stride of mip level 1+ instead of level 0."],"exampleFix":"// before\nvar buf = new PixelBuffer(w, h, format, ptr, rowStride: w); // pixels, not bytes\n// after\nint bpp = format.SizeInBytes();\nvar buf = new PixelBuffer(w, h, format, ptr, rowStride: w * bpp);","handlingStrategy":"validation","validationCode":"Image.ComputePitch(format, w, h, out var rowPitch, out _, out _, out _, PitchFlags.None);\nif (rowStride > 0 && rowStride < rowPitch)\n    throw new ArgumentException($\"rowStride {rowStride} < required {rowPitch} bytes/row.\");","typeGuard":"null","tryCatchPattern":"try { buf = new PixelBuffer(w, h, format, ptr, 0, rowStride); }\ncatch (InvalidOperationException ex) when (ex.Message.StartsWith(\"Invalid stride\"))\n{\n    rowStride = 0; // let Stride compute tight pitch\n    buf = new PixelBuffer(w, h, format, ptr, 0, rowStride);\n}","preventionTips":["Remember stride is in bytes, not pixels.","Use rowStride = 0 unless you know the buffer's real row padding.","Never reuse a smaller mip's stride for level 0.","Compute expected pitch once with Image.ComputePitch and assert against it."],"tags":["graphics","textures","stride","memory"],"backgroundTag":"value-out-of-range","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}