QL-Win/QuickLook · warning · InvalidDataException

DS_Store header too short

Error message

DS_Store header too short

What it means

Thrown by DSStoreAllocator.ReadHeader when the .DS_Store byte data is fewer than 32 bytes. A valid macOS .DS_Store file always has a 32-byte header (magic1, magic 'Bud1', root offset/size, root offset repeat, plus padding), so anything shorter cannot be parsed.

Source

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

        private readonly DSStoreBlock _root;
        private readonly List<uint> _offsets = [];
        private readonly Dictionary<string, uint> _toc = new(StringComparer.Ordinal);

        public DSStoreAllocator(byte[] data)
        {
            _data = data ?? throw new ArgumentNullException(nameof(data));
            _pos = 0;
            var (offset, size) = ReadHeader();
            _root = NewBlock(offset, size);
            ReadOffsets();
            ReadToc();
            ReadFreeList();
        }

        private (uint offset, uint size) ReadHeader()
        {
            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;

View on GitHub (pinned to cb5d9c429c)

Solutions

  1. Check the file length is >= 32 before parsing.
  2. Skip/ignore .DS_Store files smaller than the header size rather than throwing.
  3. Re-copy the .DS_Store from the macOS source if it was truncated.
  4. Catch InvalidDataException and treat the file as having no stored filenames.

Example fix

// before
var names = DSStoreExtractor.GetFileNames(path);

// after
var info = new FileInfo(path);
if (info.Length < 32)
    return new List<string>(); // not a valid DS_Store, no filenames
var names = DSStoreExtractor.GetFileNames(path);
Defensive patterns

Strategy: validation

Validate before calling

// Skip .DS_Store files smaller than the 32-byte header.
public static List<string> SafeGetFileNames(string path)
{
    if (new FileInfo(path).Length < 32)
        return new List<string>();
    return DSStoreExtractor.GetFileNames(path);
}

Try / catch

try { var names = DSStoreExtractor.GetFileNames(path); }
catch (InvalidDataException ex) when (ex.Message == "DS_Store header too short")
{
    // File is too small to be a valid .DS_Store; return empty list.
}

Prevention

When it happens

Trigger: Calling DSStoreExtractor.GetFileNames(path) on an empty file, a near-empty placeholder .DS_Store created by a non-macOS tool, or a truncated/corrupt file under 32 bytes.

Common situations: A zero-byte .DS_Store left after a failed sync/copy; a text file renamed .DS_Store; macOS did not finish writing the file; a file from a non-HFS+/APFS filesystem that mimics the name but has no content.

Related errors


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