openjdk/jdk · error

libpng error: %s

Error message

libpng error: %s

What it means

libpng's default fatal-error handler, compiled into the JDK splashscreen. When libpng hits an unrecoverable condition (bad signature, invalid chunk CRC, malformed IHDR, out-of-memory in a png_malloc), png_default_error prints 'libpng error: <message>' and immediately png_longjmps back into the splash code's setjmp point — the function must not return. In the splashscreen context this aborts loading of the splash image.

Source

Thrown at src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c:691

      /* *Always* cancel everything out: */
      png_ptr->jmp_buf_size = 0;
      png_ptr->jmp_buf_ptr = NULL;
      png_ptr->longjmp_fn = 0;
   }
}
#endif

/* This is the default error handling function.  Note that replacements for
 * this function MUST NOT RETURN, or the program will likely crash.  This
 * function is used by default, or if the program supplies NULL for the
 * error function pointer in png_set_error_fn().
 */
static PNG_FUNCTION(void /* PRIVATE */,
png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
    PNG_NORETURN)
{
#ifdef PNG_CONSOLE_IO_SUPPORTED
   fprintf(stderr, "libpng error: %s", error_message ? error_message :
      "undefined");
   fprintf(stderr, PNG_STRING_NEWLINE);
#else
   PNG_UNUSED(error_message) /* Make compiler happy */
#endif
   png_longjmp(png_ptr, 1);
}

PNG_FUNCTION(void,PNGAPI
png_longjmp,(png_const_structrp png_ptr, int val),
    PNG_NORETURN)
{
#ifdef PNG_SETJMP_SUPPORTED
   if (png_ptr != NULL && png_ptr->longjmp_fn != NULL &&
       png_ptr->jmp_buf_ptr != NULL)
      png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
#else
   PNG_UNUSED(png_ptr)

View on GitHub (pinned to 88dfb74bbe)

Solutions

  1. Validate the PNG outside the app: 'pngcheck image.png' or open it in a browser/image editor
  2. Re-export the splash image with a mainstream tool as 8-bit RGB(A) PNG
  3. Confirm the manifest SplashScreen-Image path points at the right file inside the jar (case-sensitive, no leading slash issues)
  4. If the image is fine, ensure it was not recompressed/patched by deployment tooling (e.g. reproducible-build byte patching)
Defensive patterns

Strategy: validation

Validate before calling

// verify PNG signature before shipping/using as splash
byte[] p = Files.readAllBytes(Path.of("splash.png"));
byte[] SIG = {(byte)0x89,'P','N','G','\r','\n',0x1A,'\n'};
if (!Arrays.equals(Arrays.copyOfRange(p,0,8), SIG)) throw new IOException("not a PNG");
// plus run pngcheck in CI: pngcheck -q splash.png

Prevention

When it happens

Trigger: Passing a -splash:/-splash: image (via java -splash, jar manifest SplashScreen-Image, or JavaWS) that is corrupt, truncated, has a bad PNG signature/CRC, or uses an unsupported PNG feature. The bundled libpng parses it in native code at JVM/launcher startup or at SplashScreen.setImage() time.

Common situations: PNG truncated by a build pipeline or a partial git checkout; an image that is actually JPEG/GIF renamed to .png; PNGs written by exotic encoders with unusual chunks or 16-bit depths; download corruption of a packaged app. The splash silently fails and the app usually still starts.

Related errors


AI-assisted analysis of openjdk/jdk@88dfb74bbe (2026-08-14). Data as JSON: /api/errors/6adc536a0d1f0bc5. Report an issue: GitHub.