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
- Validate data.Length >= 22 and sniff the PNG/ICO magic bytes before calling the converter.
- Re-download the icon and verify Content-Type / length matches an image.
- Fall back to a default icon when the source cannot be parsed.
- 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
- Sniff PNG/ICO magic bytes before parsing.
- Verify downloaded icon Content-Type and length.
- Fall back to a default icon on parse failure.
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
- Backup output path not specified!
- No URL was given.
- Source directory does not exist or could not be found: {sour
- Non empty process name must be specified.
- Cannot start process, executable path is specified.
AI-assisted analysis of JosefNemec/Playnite@5911f4e964 (2026-08-13).
Data as JSON: /api/errors/2f6ce94f310a4406.
Report an issue: GitHub.