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
- Validate the PNG outside the app: 'pngcheck image.png' or open it in a browser/image editor
- Re-export the splash image with a mainstream tool as 8-bit RGB(A) PNG
- Confirm the manifest SplashScreen-Image path points at the right file inside the jar (case-sensitive, no leading slash issues)
- 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
- Run pngcheck on splash assets in CI so corrupt PNGs fail the build, not the launch
- Keep splash images as 8-bit RGB/RGBA exported from a mainstream tool
- Never rename non-PNG files to .png for the splash
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
- libpng warning: %s
- %s\n
- Could not create SplashScreen thread, error number:%d\n
- Error: Out of memory in ADLC\n
- JVM caught ASAN Error
AI-assisted analysis of openjdk/jdk@88dfb74bbe (2026-08-14).
Data as JSON: /api/errors/6adc536a0d1f0bc5.
Report an issue: GitHub.