SubtitleEdit/subtitleedit · warning · InvalidOperationException

Unknown byte (0x{b:X2}) in subtitle file @ binary offset {in

Error message

Unknown byte (0x{b:X2}) in subtitle file @ binary offset {index}.

What it means

Thrown by Pac.GetCyrillicString when a byte (or its two-byte sequence) does not map in CyrillicCodes and Pac.ThrowOnError=true. Decimal digits 0x30-0x39 pass through as ASCII first. The message uses hex (0xNN) format for the byte. Default false returns empty.

Source

Thrown at src/libse/SubtitleFormats/Pac.cs:2663

            if (buffer.Length > index + 1)
            {
                var code = b * 256 + buffer[index + 1];
                if (CyrillicCodes.ContainsKey(code))
                {
                    index++;
                    return CyrillicCodes[code].Character;
                }
            }

            if (CyrillicCodes.ContainsKey(b))
            {
                return CyrillicCodes[b].Character;
            }

            if (ThrowOnError)
            {
                throw new InvalidOperationException($"Unknown byte (0x{b:X2}) in subtitle file @ binary offset {index}.");
            }

            return string.Empty;
        }

        public static string GetGreekString(byte[] buffer, ref int index, bool isSecondary)
        {
            var b = buffer[index];

            if (b >= 0x30 && b <= 0x39) // decimal digits
            {
                return Encoding.ASCII.GetString(buffer, index, 1);
            }

            if (isSecondary && (buffer[index] == 0x2d || buffer[index] == 0x5f))
            {
                return GetLatinString(Encoding.ASCII, buffer, ref index, new Dictionary<int, SpecialCharacter>());
            }

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Keep Pac.ThrowOnError = false to skip unmapped bytes.
  2. Verify the file is a Cyrillic-language PAC.
  3. Re-export/re-acquire the file if corruption is suspected.
  4. Extend CyrillicCodes for legitimate but unmapped glyphs.

Example fix

// before
Pac.ThrowOnError = true;
// after
Pac.ThrowOnError = false;
Defensive patterns

Strategy: validation

Validate before calling

// Tolerant mode skips unmapped Cyrillic bytes
Pac.ThrowOnError = false;
new Pac().LoadSubtitle(sub, lines, fileName);

Try / catch

Pac.ThrowOnError = true;
try
{
    new Pac().LoadSubtitle(sub, lines, fileName);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Unknown byte"))
{
    logger.Warning(ex.Message); // hex byte and offset included
}

Prevention

When it happens

Trigger: Decoding a PAC Cyrillic track where a byte or byte-pair has no CyrillicCodes entry and is not a digit — e.g. an unmapped high byte or a broken two-byte sequence. Only throws when ThrowOnError is enabled.

Common situations: Misidentified language (file is not Russian/Cyrillic), corrupt bytes, or a Cyrillic variant whose glyph table differs from this build.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/1b4a2fe62b33520b. Report an issue: GitHub.