JosefNemec/Playnite · warning · ArgumentException

The icon is corrupt. Couldn't read the header.

Error message

The icon is corrupt. Couldn't read the header.

What it means

Thrown by IconUtil when byte data passed to read an icon is neither a recognized PNG header nor large enough to read an ICONDIRENTRY (data.Length < 22 or an unrecognized structure). The argument name is 'icon'; it signals the icon bytes are malformed/truncated.

Source

Thrown at source/Playnite/Common/Media/Icons/IconUtil.cs:182

                    case 3:
                        return data[46];
                    case 4:
                        return data[46] * 2;
                    case 6:
                        return data[46] * 4;
                    default:
                        // NOP
                        break;
                }
            }
            else if (data.Length >= 22)
            {
                // The picture is not PNG. Read ICONDIRENTRY structure.

                return BitConverter.ToUInt16(data, 12);
            }

            throw new ArgumentException("The icon is corrupt. Couldn't read the header.", "icon");
        }

        private static byte[] GetIconData(Icon icon)
        {
            var data = getIconData(icon);
            if (data != null)
            {
                return data;
            }
            else
            {
                using (var ms = new MemoryStream())
                {
                    icon.Save(ms);
                    return ms.ToArray();
                }
            }
        }

View on GitHub (pinned to 5911f4e964)

Solutions

  1. Validate data.Length >= 22 and sniff the PNG/ICO magic bytes before calling the converter.
  2. Re-download the icon and verify Content-Type / length matches an image.
  3. Fall back to a default icon when the source cannot be parsed.
  4. Check the source file is a genuine .ico and not a renamed JPEG/PNG.

Example fix

// before
var size = IconUtil.GetIconSize(bytes);

// after — sniff magic bytes before parsing
if (bytes == null || bytes.Length < 22) return null;
bool isPng = bytes.Length >= 8 && bytes[0] == 0x89 && bytes[1] == 'P';
if (!isPng && BitConverter.ToUInt16(bytes, 0) != 0) return null; // not ICO
var size = IconUtil.GetIconSize(bytes);
Defensive patterns

Strategy: validation

Validate before calling

if (data == null || data.Length < 22) return null;
bool isPng = data.Length >= 8 && data[0] == 0x89 && data[1] == (byte)'P' && data[2] == (byte)'N' && data[3] == (byte)'G';
if (!isPng && BitConverter.ToUInt16(data, 0) != 0) return null; // not an ICO

Type guard

static bool LooksLikeIcon(byte[] d) => d != null && d.Length >= 22 &&
    (IsPng(d) || BitConverter.ToUInt16(d, 0) == 0);

Try / catch

try { return IconUtil.GetIconSize(bytes); }
catch (ArgumentException) { return null; /* corrupt icon — fall back to default */ }

Prevention

When it happens

Trigger: Passing a corrupt, zero-byte, or truncated icon file/byte array; passing bytes that are not an icon at all (e.g. a JPEG mislabeled .ico); a downloaded icon whose transfer was interrupted leaving < 22 bytes.

Common situations: Fetching a game icon from a metadata provider that returned an HTML error page instead of image bytes; reading a .ico while it was being rewritten; user-supplied icon file that is actually a renamed PNG/JPEG with an unreadable header.

Related errors


AI-assisted analysis of JosefNemec/Playnite@5911f4e964 (2026-08-13). Data as JSON: /api/errors/2f6ce94f310a4406. Report an issue: GitHub.