QL-Win/QuickLook · error · InvalidDataException

DS_Store: unknown record type '{stype}'

Error message

DS_Store: unknown record type '{stype}'

What it means

Thrown while parsing a macOS .DS_Store file: after skipping a 4-byte sid and reading a 4-byte ASCII type tag, the tag did not match any of the known record types (bool, type, long, shor, comp, dutc, blob, ustr). This is an InvalidDataException signalling that the parser encountered a structure it cannot decode. The QuickLook ArchiveViewer uses this to bail out on a malformed or unsupported .DS_Store embedded inside a ZIP/archive.

Source

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

        public string ReadFileName()
        {
            uint   length = ReadUint32();
            byte[] buf    = ReadBuf((int)(2 * length));

            // skip sid (4 bytes) and read type tag (4 bytes)
            Skip(4);
            byte[] stypeBytes = ReadBuf(4);
            string stype      = Encoding.ASCII.GetString(stypeBytes);

            int bytesToSkip = stype switch
            {
                "bool"           => 1,
                "type" or "long" or "shor" => 4,
                "comp" or "dutc" => 8,
                "blob"           => (int)ReadUint32(),
                "ustr"           => (int)(2 * ReadUint32()),
                _                => throw new InvalidDataException($"DS_Store: unknown record type '{stype}'")
            };

            Skip((uint)bytesToSkip);

            // filename is encoded as UTF-16 big-endian
            return Encoding.BigEndianUnicode.GetString(buf);
        }
    }
}

View on GitHub (pinned to cb5d9c429c)

Solutions

  1. Confirm the file is a genuine .DS_Store (magic 'Bud1\0' at offset 0) before invoking the extractor.
  2. If you control the parser, map the new tag to its documented size instead of throwing, or extend the switch with the missing case.
  3. Wrap the extraction in a try/catch for InvalidDataException and fall back to skipping the .DS_Store entry when previewing an archive.
  4. Re-download or re-create the archive if the .DS_Store is byte-corrupted.

Example fix

// before
_ => throw new InvalidDataException($"DS_Store: unknown record type '{stype}'")

// after: tolerate unknown tags by reading a length-prefixed value when present
_ => (int)ReadUint32()
Defensive patterns

Strategy: validation

Validate before calling

// verify .DS_Store magic 'Bud1\0' (0x42756431 then 0x0000) before parsing
using var fs = File.OpenRead(path);
Span<byte> magic = stackalloc byte[8];
if (await fs.ReadAsync(magic) < 8) return false;
return magic[0]=='B' && magic[1]=='u' && magic[2]=='d' && magic[3]=='1' && magic[4]==0 && magic[5]==0;

Type guard

static bool IsLikelyDsStore(byte[] head) => head.Length >= 8 && head[0]=='B' && head[1]=='u' && head[2]=='d' && head[3]=='1';

Try / catch

try { DSStoreExtractor.Extract(stream); }
catch (InvalidDataException) { /* skip this .DS_Store entry, continue archive preview */ }

Prevention

When it happens

Trigger: ReadBuf(4) returns 4 bytes whose ASCII decoding is not one of {bool, type, long, shor, comp, dutc, blob, ustr}; the switch expression falls to its '_' arm. Happens when the .DS_Store stream is truncated, byte-shifted, or produced by a macOS version that emits a record type this parser does not know.

Common situations: Corrupted download of a macOS archive; a .DS_Store rewritten by a newer macOS release that introduced a new value type; a file that merely has a .DS_Store name but is not actually a Finder .DS_Store; partial extraction leaving the record header incomplete.

Related errors


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