HMCL-dev/HMCL · error · PngIntegrityException
Received tRNS data length is invalid. Should be >1 && <
Error message
Received tRNS data length is invalid. Should be >1 && < %d but is %d
What it means
Thrown by processTransparentPalette when a tRNS chunk's data length is zero or exceeds the number of entries in the established PLTE palette. The library validates that transparency alpha values map onto existing palette indices; a mismatched length means the chunk is malformed or out of order.
Solutions
- Verify the tRNS chunk data length in the PNG file does not exceed the PLTE entry count (length must be 1..paletteSize).
- Ensure the PLTE chunk is parsed before tRNS so the palette is in place and sized correctly.
- Re-export or re-save the PNG with a compliant encoder (e.g. ImageMagick, pngcrush) to regenerate a valid tRNS chunk.
- Catch PngIntegrityException around decode and treat the file as invalid input.
Example fix
// before: trusting chunk length
readTransparentPalette(bytes, pos, chunkLength);
// after: clamp/validate against palette
int safe = Math.min(chunkLength, palette.size());
if (safe <= 0) throw new PngIntegrityException("empty tRNS");
readTransparentPalette(bytes, pos, safe); Defensive patterns
Strategy: try-catch
Validate before calling
// parse chunk table first
if (trnsLength < 1 || trnsLength > plteEntryCount) throw new IllegalArgumentException("bad tRNS length"); Try / catch
try { director.processTransparentPalette(bytes, pos, len); } catch (PngIntegrityException e) { log.warn("Invalid tRNS: " + e.getMessage()); fallbackToOpaqueRendering(); } Prevention
- Validate tRNS length against PLTE entry count before decoding.
- Ensure PLTE is processed before tRNS.
- Re-encode suspect images with a compliant PNG tool.
- Add pngcheck to ingestion pipelines to pre-screen files.
When it happens
Trigger: A tRNS chunk arrives with length 0, or with more bytes than the palette size (palette.size()), or a tRNS is delivered without any palette having been processed (that raises a different message, but wrong order can lead to stale palette sizes).
Common situations: Hand-edited or corrupted PNG files, PNG steganography test images, chunk streams where tRNS precedes PLTE or was truncated by a partial download.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Invalid bit depth
- Indexed images (colour type ) cannot have bitdepth > 8 (bit…
- Illegal combination of bit depth
- Invalid palette data length
- bKGD chunk received before IHDR chunk
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/7854ca546e4954aa.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/ui/image/apng/argb8888/BasicArgb8888Director.java:27
/**
* Common functionality for Argb8888Director implementations.
*/
public abstract class BasicArgb8888Director<ResultT> implements Argb8888Director<ResultT> {
protected Argb8888ScanlineProcessor scanlineProcessor;
@Override
public void receivePalette(Argb8888Palette palette) {
scanlineProcessor.setPalette(palette);
}
@Override
public void processTransparentPalette(byte[] bytes, int position, int length) throws PngException {
Argb8888Palette palette = scanlineProcessor.getPalette();
if (null == palette) {
throw new PngIntegrityException("Received tRNS data but no palette is in place");
}
if (length <= 0 || length > palette.size()) {
throw new PngIntegrityException(String.format("Received tRNS data length is invalid. Should be >1 && < %d but is %d", palette.size(), length));
}
for (int i = 0; i < length; i++) {
final int alpha = 0xff & bytes[position + i];
palette.argbArray()[i] = alpha << 24 | palette.argbArray()[i] & 0x00FFFFFF;
}
}
@Override
public void processTransparentGreyscale(byte k1, byte k0) throws PngException {
scanlineProcessor.processTransparentGreyscale(k1, k0);
}
@Override
public void processTransparentTruecolour(byte r1, byte r0, byte g1, byte g0, byte b1, byte b0) throws PngException {
scanlineProcessor.processTransparentTruecolour(r1, r0, g1, g0, b1, b0);
}
}View on GitHub (pinned to 24702dc5a0)