stride3d/stride · error · ArgumentException
Pointer to DDS header cannot be null
Error message
Pointer to DDS header cannot be null
What it means
DecodeDDSHeader validates the incoming pointer to a DDS header before parsing. A null/IntPtr.Zero pointer cannot contain a header, so it immediately throws ArgumentException naming the headerPtr parameter, mirroring DirectXTex's behavior.
Solutions
- Ensure the buffer containing DDS data is loaded and non-empty before decoding
- Check any pointer-producing call (AllocGCHandle, Alloc, native alloc) for failure and handle IntPtr.Zero before calling
- Fix the data-loading path so the DDS bytes are actually read into memory
Example fix
// before
if (dataPtr == IntPtr.Zero) { /* unchecked */ }
DecodeDDS(dataPtr, size, ...);
// after
if (dataPtr == IntPtr.Zero) throw new InvalidOperationException("DDS data not loaded");
DecodeDDS(dataPtr, size, ...); Defensive patterns
Strategy: validation
Validate before calling
if (headerPtr == IntPtr.Zero)
throw new InvalidOperationException("DDS data buffer was not loaded; cannot decode header");
if (size < 4 + sizeof(DDS.Header))
throw new InvalidOperationException("DDS buffer too small to contain a header"); Try / catch
try { ok = DecodeDDSHeader(ptr, size, flags, out desc, out conv); } catch (ArgumentException ex) when (ex.ParamName == "headerPtr") { // fix data loading before retry
throw new InvalidOperationException("DDS source pointer was null; load the file bytes first", ex); } Prevention
- Always load DDS bytes into memory before decoding
- Check pointer-returning allocation APIs for IntPtr.Zero
- Assert non-null pointers near the interop boundary
- Wrap native decode calls behind a managed loader that validates inputs
When it happens
Trigger: Calling DDS loading/decoding APIs (Image.Load / DDS decoding path) with IntPtr.Zero as the header pointer, typically from a failed buffer pin/allocation, passing an uninitialized pointer, or a null byte[] marshaled to pointer.
Common situations: P/Invoke or unsafe interop returning IntPtr.Zero on failure that is then passed to the DDS decoder, loading from a stream/buffer where the data pointer was never set, custom native integrations.
Related errors
- Unexpected ArraySize == 0 from DDS HeaderDX10
- Invalid Format from DDS HeaderDX10
- Unexpected Height != 1 from DDS HeaderDX10
- Texture3D missing HeaderFlags.Volume from DDS HeaderDX10
- Unexpected ArraySize > 1 for Texture3D from DDS HeaderDX10
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/856feab575f54c2f.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Foundation/Graphics/DDSHelper.cs:299
/// <summary>
/// Decodes DDS header including optional DX10 extended header
/// </summary>
/// <param name="headerPtr">Pointer to the DDS header.</param>
/// <param name="size">Size of the DDS content.</param>
/// <param name="flags">Flags used for decoding the DDS header.</param>
/// <param name="description">Output texture description.</param>
/// <param name="convFlags">Output conversion flags.</param>
/// <exception cref="ArgumentException">If the argument headerPtr is null</exception>
/// <exception cref="InvalidOperationException">If the DDS header contains invalid datas.</exception>
/// <returns>True if the decoding is successfull, false if this is not a DDS header.</returns>
private static unsafe bool DecodeDDSHeader(IntPtr headerPtr, int size, DDSFlags flags, out ImageDescription description, out ConversionFlags convFlags)
{
description = new ImageDescription();
convFlags = ConversionFlags.None;
if (headerPtr == IntPtr.Zero)
throw new ArgumentException("Pointer to DDS header cannot be null", "headerPtr");
if (size < (Unsafe.SizeOf<DDS.Header>() + sizeof (uint)))
return false;
// DDS files always start with the same magic number ("DDS ")
if (*(uint*) (headerPtr) != DDS.MagicHeader)
return false;
var header = *(DDS.Header*) ((byte*) headerPtr + sizeof (int));
// Verify header to validate DDS file
if (header.Size != Unsafe.SizeOf<DDS.Header>() || header.PixelFormat.Size != Unsafe.SizeOf<DDS.DDSPixelFormat>())
return false;
// Setup MipLevels
description.MipLevels = header.MipMapCount;
if (description.MipLevels == 0)
description.MipLevels = 1;View on GitHub (pinned to 96fad776d2)