HMCL-dev/HMCL · error · PngIntegrityException
Invalid palette data length
Error message
Invalid palette data length: %d (not a multiple of 3)
What it means
This validation in PngPalette.from fires when a PLTE chunk's data length is not divisible by 3. Each palette entry is exactly 3 bytes (R, G, B), so a length that is not a multiple of 3 means the chunk is truncated or corrupt and the palette cannot be parsed into whole RGB triplets.
Solutions
- Re-encode or re-save the PNG with a compliant tool to regenerate a valid PLTE.
- Verify the chunk length against the file's chunk table; check for truncation in transfer.
- Catch PngIntegrityException and reject the image as corrupt.
Example fix
// before
PngPalette.from(source, first, length);
// after
if (length % 3 != 0) {
throw new PngIntegrityException("PLTE length " + length + " not multiple of 3");
}
PngPalette.from(source, first, length); Defensive patterns
Strategy: try-catch
Validate before calling
if (plteLength % 3 != 0) throw new IllegalArgumentException("PLTE length not multiple of 3"); Try / catch
try { PngPalette.from(source, first, length); } catch (PngIntegrityException e) { handleCorruptPalette(e); } Prevention
- Check PLTE length % 3 == 0 during chunk pre-scan.
- Re-encode corrupted files.
- Use pngcheck to pre-screen.
- Avoid manual chunk editing.
When it happens
Trigger: A PLTE chunk whose dataLength is not a multiple of 3, from truncation, corruption, or a broken encoder.
Common situations: Corrupted downloads, files edited with hex editors, fuzzed test inputs, faulty custom PNG writers.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- png spec: palette chunk length must be divisible by 3
- Received tRNS data length is invalid. Should be >1 && <
- Invalid bit depth
- Indexed images (colour type ) cannot have bitdepth > 8 (bit…
- Illegal combination of bit depth
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/04b3c23d51edd39e.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/ui/image/apng/chunks/PngPalette.java:40
*/
public class PngPalette {
// TODO: should include alpha here? Can then store as int32s?
public final byte[] rgb888;
public final int[] rgba8888; // Including this duplicate for now. Not sure if will keep it.
public final int numColours;
public static final int LENGTH_RGB_BYTES = 3;
public static final int BYTE_INITIAL_ALPHA = 0xff;
public PngPalette(byte[] rgb888, int[] rgba8888) {
this.rgb888 = rgb888;
this.rgba8888 = rgba8888;
this.numColours = rgb888.length / 3;
}
public static PngPalette from(byte[] source, int first, int length) throws PngException {
if (length % LENGTH_RGB_BYTES != 0) {
throw new PngIntegrityException(String.format("Invalid palette data length: %d (not a multiple of 3)", length));
}
return new PngPalette(
Arrays.copyOfRange(source, first, first + length),
rgba8888From(source, first, length)
);
}
private static int[] rgba8888From(byte[] source, int first, int length) {
int last = first + length;
int numColours = length / 3;
int[] rgba8888 = new int[numColours];
int j = 0;
for (int i = first; i < last; i += LENGTH_RGB_BYTES) {
rgba8888[j] = source[i] << 24 | source[i + 1] << 16 | source[i + 2] << 8 | BYTE_INITIAL_ALPHA;
j++;
}
return rgba8888;View on GitHub (pinned to 24702dc5a0)