QL-Win/QuickLook · warning · InvalidDataException

DS_Store: root-block offset mismatch

Error message

DS_Store: root-block offset mismatch

What it means

Thrown by DSStoreAllocator.ReadHeader when the root-block offset read at bytes 8-11 does not equal the offset read at bytes 16-19. A valid .DS_Store header stores the root offset twice for consistency; a mismatch signals corruption or a non-standard writer.

Source

Thrown at QuickLook.Plugin/QuickLook.Plugin.ArchiveViewer/DSStore/DSStoreExtractor.cs:83

        {
            if (_data.Length < 32)
                throw new InvalidDataException("DS_Store header too short");

            uint magic1 = ReadUint32BE(_data, (int)_pos);
            if (magic1 != 1)
                throw new InvalidDataException("DS_Store: wrong magic (expected 0x00000001)");
            _pos += 4;

            uint magic = ReadUint32BE(_data, (int)_pos);
            if (magic != 0x42756431u)
                throw new InvalidDataException("DS_Store: wrong magic (expected 'Bud1')");
            _pos += 4;

            uint offset = ReadUint32BE(_data, (int)_pos); _pos += 4;
            uint size   = ReadUint32BE(_data, (int)_pos); _pos += 4;
            uint offset2 = ReadUint32BE(_data, (int)_pos);
            if (offset != offset2)
                throw new InvalidDataException("DS_Store: root-block offset mismatch");
            _pos += 4;

            return (offset, size);
        }

        private DSStoreBlock NewBlock(uint pos, uint size)
        {
            if (_data.Length < pos + 4 + size)
                throw new InvalidDataException("DS_Store: not enough data for block");
            var buf = new byte[size];
            Buffer.BlockCopy(_data, (int)pos + 4, buf, 0, (int)size);
            return new DSStoreBlock(this, pos, size, buf);
        }

        private void ReadOffsets()
        {
            uint count = _root.ReadUint32();
            _root.Skip(4);

View on GitHub (pinned to cb5d9c429c)

Solutions

  1. Catch InvalidDataException and treat the file as unparseable, returning no filenames.
  2. Re-copy the .DS_Store from the original macOS volume.
  3. If you control the writer, ensure both root-offset fields are written atomically.
  4. Validate header consistency before trusting the offsets.
Defensive patterns

Strategy: try-catch

Try / catch

try { var names = DSStoreExtractor.GetFileNames(path); }
catch (InvalidDataException ex) when (ex.Message.Contains("root-block offset mismatch"))
{
    // Header is internally inconsistent; treat as unparseable.
    names = new List<string>();
}

Prevention

When it happens

Trigger: Calling GetFileNames on a .DS_Store whose header's two root-offset fields disagree: bit-flip corruption, partial overwrite, an inconsistent third-party writer, or an incomplete write.

Common situations: File corrupted in transit or by a disk error; a .DS_Store modified by a non-macOS tool that did not maintain both offset copies; a file from a crashed/aborted macOS write.

Related errors


AI-assisted analysis of QL-Win/QuickLook@cb5d9c429c (2026-08-13). Data as JSON: /api/errors/18bf79f29c7bdfc9. Report an issue: GitHub.