pixijs/pixijs · error · Error

Invalid magic number in DDS header

Error message

Invalid magic number in DDS header

What it means

Thrown by parseDDSHeader when the first 32-bit word of the file does not equal the DDS magic value ('DDS ' = 0x20534444). This is the canonical sanity check that the byte stream is actually a DDS file before trusting any header fields.

Source

Thrown at src/compressed-textures/dds/parseDDS.ts:89

        levelBuffers.push(levelBuffer);

        offset += byteLength;

        mipWidth = Math.max(mipWidth >> 1, 1);
        mipHeight = Math.max(mipHeight >> 1, 1);
    }

    return levelBuffers;
}

function parseDDSHeader(buffer: ArrayBuffer)
{
    const header = new Uint32Array(buffer, 0, DDS.HEADER_SIZE / Uint32Array.BYTES_PER_ELEMENT);

    if (header[DDS.HEADER_FIELDS.MAGIC] !== DDS.MAGIC_VALUE)
    {
        throw new Error('Invalid magic number in DDS header');
    }

    // DDS header fields
    const height = header[DDS.HEADER_FIELDS.HEIGHT];
    const width = header[DDS.HEADER_FIELDS.WIDTH];
    const mipmapCount = Math.max(1, header[DDS.HEADER_FIELDS.MIPMAP_COUNT]);
    const flags = header[DDS.HEADER_FIELDS.PF_FLAGS];
    const fourCC = header[DDS.HEADER_FIELDS.FOURCC];
    const format = getTextureFormat(header, flags, fourCC, buffer);

    const dataOffset = DDS.MAGIC_SIZE + DDS.HEADER_SIZE
        + ((fourCC === DDS.D3DFMT.DX10) ? DDS.HEADER_DX10_SIZE : 0);

    return {
        format,
        fourCC,
        width,
        height,

View on GitHub (pinned to 4b141e3ced)

Solutions

  1. Verify the file starts with bytes 'DDS ' (0x44 0x44 0x53 0x20) using a hex viewer.
  2. Confirm the URL returns the actual binary DDS (check Content-Type and that it is not an HTML fallback).
  3. Re-export or re-download the DDS in binary mode without transformation.
  4. Ensure no text-mode read or base64 double-encoding is applied to the file.

Example fix

// before
await Assets.load('textures/floor.dds'); // actually returns HTML SPA fallback

// after
// fix server to return the real .dds binary (200, application/octet-stream)
Defensive patterns

Strategy: validation

Validate before calling

// Verify the DDS magic before handing the buffer to the parser
function isDdsMagic(buf: ArrayBuffer): boolean {
  const v = new Uint32Array(buf, 0, 1)[0];
  return v === 0x20534444; // 'DDS '
}

Type guard

function isDdsBuffer(buf: ArrayBuffer): boolean {
  if (buf.byteLength < 4) return false;
  return new Uint32Array(buf, 0, 1)[0] === 0x20534444;
}

Try / catch

try {
  await Assets.load(url);
} catch (err) {
  if (String(err).includes('Invalid magic number in DDS header')) {
    // wrong file or HTML fallback; verify URL and Content-Type
  } else throw err;
}

Prevention

When it happens

Trigger: Pointing the DDS loader at a non-DDS file (PNG/JSON/text/binary garbage), a truncated file (fewer than 4 bytes), a file that was decompressed/corrupted in transit, or a wrong byte order (endianness). Also a misrouted URL that returns HTML (e.g. a 200 SPA fallback) and is parsed as DDS.

Common situations: Asset name collision where a .dds URL actually returns an HTML 404 page (200 status), a build tool that mangles binary files, or downloading the file in text mode corrupting bytes.

Related errors


AI-assisted analysis of pixijs/pixijs@4b141e3ced (2026-08-12). Data as JSON: /api/errors/890eb4443092dcef. Report an issue: GitHub.