stride3d/stride · error · InvalidOperationException
SPIRV Magic number not found
Error message
SPIRV Magic number not found
What it means
ShaderBuffers.CreateFromSpan parses a SPIR-V binary module from an int span. The first word of a SPIR-V module must be the Specification.MagicNumber (0x07230203); if it is not, the method throws InvalidOperationException('SPIRV Magic number not found'), meaning the input is not a valid SPIR-V module (or the span is misaligned/shifted).
Solutions
- Verify the input actually contains a SPIR-V module (first 4 bytes = 03 02 23 07 little-endian)
- If the blob has a wrapper, skip to the correct offset before calling CreateFromSpan
- Check endianness when converting raw bytes to Span<int>; swap bytes if the producer was big-endian
Example fix
// before
var buffers = ShaderBuffers.CreateFromSpan(bytes.AsSpan().Cast<byte, int>());
// after
if (BitConverter.IsLittleEndian && bytes[0] == 0x03 && bytes[1] == 0x02 && bytes[2] == 0x23 && bytes[3] == 0x07)
var buffers = ShaderBuffers.CreateFromSpan(MemoryMarshal.Cast<byte, int>(bytes)); Defensive patterns
Strategy: validation
Validate before calling
const int SpirvMagic = 0x07230203;
bool LooksLikeSpirv(ReadOnlySpan<int> span) => span.Length >= 5 && span[0] == SpirvMagic;
if (!LooksLikeSpirv(span)) throw new InvalidOperationException("Input is not a SPIR-V module (bad magic number)"); Type guard
static bool IsSpirvBinary(ReadOnlySpan<byte> bytes) => bytes.Length >= 4 && bytes[0] == 0x03 && bytes[1] == 0x02 && bytes[2] == 0x23 && bytes[3] == 0x07;
Try / catch
try { var buffers = ShaderBuffers.CreateFromSpan(span); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Magic number")) { Log("Not a SPIR-V module: " + ex.Message); return null; } Prevention
- Verify the file/container actually stores SPIR-V (magic 03 02 23 07 LE) before parsing
- Strip any container headers/footers before slicing the span
- Beware endianness when converting byte[] to int[]; SPIR-V words are little-endian
- Sanity-check word count against the header's word-count field before processing
When it happens
Trigger: Passing a span whose first int is not 0x07230203 — e.g. a GLSL/assembly text buffer, a SPIR-V blob with a prepended header, byte-order-swapped data from an endianness mismatch, or an offset-into-module span starting past the header.
Common situations: Reading compiled SPIR-V from a custom container that stores extra metadata before the module; loading DXIL/other shaders by mistake; converting byte[] to int[] with wrong endianness (SPIR-V is little-endian on LE hosts).
Related errors
- Not a SPIR-V module
- SPIRV Magic number not found
- Unsupported binary op
- 64bit integers
- A negative number of mip maps is not allowed.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/b181f678d7c8399f.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs:34
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Stride.Core.Storage;
using static Stride.Shaders.Spirv.Specification;
using Stride.Shaders.Spirv.Core.Parsing;
using System.Diagnostics.CodeAnalysis;
namespace Stride.Shaders.Spirv.Building;
public record class ShaderMixinInstantiation(List<ShaderClassInstantiation> Mixins, Dictionary<string, ShaderMixinInstantiation[]> Compositions);
public record struct ShaderBuffers(SpirvContext Context, SpirvBuffer Buffer)
{
public static ShaderBuffers CreateFromSpan(Span<int> span)
{
if (span[0] != Specification.MagicNumber)
throw new InvalidOperationException("SPIRV Magic number not found");
var header = SpirvHeader.Read(span);
var context = new SpirvContext();
var buffer = new SpirvBuffer();
int wid = SpirvHeader.IntSpanSize;
bool isContext = true;
while (wid < span.Length)
{
var instruction = new OpData(span.Slice(wid, span[wid] >> 16));
if (instruction.Op == Op.OpShaderSDSL)
isContext = false;
(isContext ? context.GetBuffer() : buffer).Add(instruction);
wid += span[wid] >> 16;
}
return new(context, buffer);View on GitHub (pinned to 96fad776d2)