HMCL-dev/HMCL · error · IOException

No image found

Error message

No image found

What it means

Texture.loadTexture(InputStream) wraps the stream in a JavaFX Image and throws IOException("No image found") when img.isError() reports the decoder failed. It means the provided bytes are not a decodable image (or are corrupt), so the skin/cape texture cannot be loaded.

Solutions

  1. Verify the input is a valid PNG image (open in an image viewer or check magic bytes) before loading.
  2. Re-download the skin/texture from the source server and retry.
  3. Check the wrapped img.getException() for the underlying decode cause and fix the data source accordingly.
  4. Return null / use a default texture when loading optional skins fails.

Example fix

// before
Texture t = Texture.loadTexture(Files.newInputStream(path));
// after
try (InputStream is = Files.newInputStream(path)) {
    Texture t = Texture.loadTexture(is);
    if (t == null) log.warning("Texture unreadable, using default skin");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// check magic bytes before decoding
byte[] head = new byte[8];
try (InputStream in = stream) {
    if (in.read(head) != 8) throw new IOException("Texture stream too short");
    boolean isPng = (head[0] & 0xFF) == 0x89 && head[1] == 'P' && head[2] == 'N' && head[3] == 'G';
    if (!isPng) throw new IOException("Not a PNG texture");
}

Try / catch

try {
    Texture t = Texture.loadTexture(inputStream);
} catch (IOException e) {
    // fall back to default skin, log img.getException() cause
}

Prevention

When it happens

Trigger: Calling Texture.loadTexture(InputStream) with an empty stream, non-image data (e.g. HTML error page, JSON), truncated PNG, or unsupported format that JavaFX cannot decode.

Common situations: Skin server returning 404/HTML instead of PNG; corrupted local skin cache files; user-selected file that is not a real PNG; interrupted downloads.

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


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/04385205546fa822. Report an issue: GitHub.

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/auth/offline/Texture.java:100

        return HexFormat.of().formatHex(digest.digest());
    }

    private static void putInt(byte[] array, int offset, int x) {
        array[offset + 0] = (byte) (x >> 24 & 0xff);
        array[offset + 1] = (byte) (x >> 16 & 0xff);
        array[offset + 2] = (byte) (x >> 8 & 0xff);
        array[offset + 3] = (byte) (x >> 0 & 0xff);
    }

    public static Texture loadTexture(InputStream in) throws IOException {
        if (in == null) return null;
        Image img;
        try (InputStream is = in) {
            img = new Image(is);
        }

        if (img.isError()) {
            throw new IOException("No image found", img.getException());
        }
        return loadTexture(img);
    }

    public static Texture loadTexture(Image image) {
        if (image == null) return null;

        String hash = computeTextureHash(image);

        Texture existent = textures.get(hash);
        if (existent != null) {
            return existent;
        }

        Texture texture = new Texture(hash, image);
        existent = textures.putIfAbsent(hash, texture);

        if (existent != null) {

View on GitHub (pinned to 24702dc5a0)