openjdk/jdk · info

%s\n

Error message

%s\n

What it means

This is not one error but the JDK's jpegdecoder.c replacement for libjpeg's default output_message callback: every warning or recoverable error that libjpeg emits while decoding (via format_message) is printed to stderr with a newline. Seeing this format string in a log means libjpeg produced a diagnostic — the actual text (e.g. 'Corrupt JPEG data: premature end of data segment', 'Unsupported marker type') is in the buffer, not in the format itself.

Source

Thrown at src/java.desktop/share/native/libjavajpeg/jpegdecoder.c:142

}

/*
 * Error Message handling
 *
 * This overrides the output_message method to send JPEG messages
 *
 */

METHODDEF(void)
sun_jpeg_output_message (j_common_ptr cinfo)
{
  char buffer[JMSG_LENGTH_MAX];

  /* Create the message */
  (*cinfo->err->format_message) (cinfo, buffer);

  /* Send it to stderr, adding a newline */
  fprintf(stderr, "%s\n", buffer);
}




/*
 * INPUT HANDLING:
 *
 * The JPEG library's input management is defined by the jpeg_source_mgr
 * structure which contains two fields to convey the information in the
 * buffer and 5 methods which perform all buffer management.  The library
 * defines a standard input manager that uses stdio for obtaining compressed
 * jpeg data, but here we need to use Java to get our data.
 *
 * We need to make the Java class information accessible to the source_mgr
 * input routines.  We also need to store a pointer to the start of the
 * Java array being used as an input buffer so that it is not moved or
 * garbage collected while the JPEG library is using it.  To store these

View on GitHub (pinned to 88dfb74bbe)

Solutions

  1. Read the message text after the format — it names the exact libjpeg problem; address that (re-save the image, fix transfer, strip EXIF)
  2. Verify the file is a complete JPEG: check SOI/EOI markers (FFD8...FFD9) and file size before decoding
  3. Re-encode the problem image with a standard tool (cjpeg/ImageMagick) to normalize markers and color space
  4. If the image is under your control, export baseline RGB JPEG rather than progressive/CMYK
Defensive patterns

Strategy: validation

Validate before calling

// before decoding, verify JPEG SOI/EOI and size
byte[] b = Files.readAllBytes(Path.of("img.jpg"));
boolean looksLikeJpeg = b.length > 4
    && (b[0] & 0xFF) == 0xFF && (b[1] & 0xFF) == 0xD8
    && (b[b.length-2] & 0xFF) == 0xFF && (b[b.length-1] & 0xFF) == 0xD9;
if (!looksLikeJpeg) throw new IOException("not a complete JPEG");

Try / catch

catch (IOException | ArrayIndexOutOfBoundsException e) when loading; the stderr line itself is non-fatal libjpeg diagnostics — decide on partial-image acceptability

Prevention

When it happens

Trigger: Toolkit.createImage()/ImageIO-style loading (via sun.awt.image JPEG decoder) of a JPEG that is truncated, has corrupt Huffman data, unknown JPEG markers, or uses progressive/color profiles libjpeg only partially supports. Each such condition makes libjpeg call output_message, which prints and, for warnings, continues decoding.

Common situations: Downloading images over flaky connections producing truncated files; camera-generated JPEGs with EXIF/markers the decoder warns about; CMYK or 12-bit JPEGs; images renamed to .jpg that are actually something else. The message is informational: decoding usually still succeeds with minor artifacts.

Related errors


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