TooTallNate/Java-WebSocket · error · DataFormatException

Inflated fragment size exceeds limit of

Error message

Inflated fragment size exceeds limit of {maxFragmentSize} bytes

What it means

PerMessageDeflateExtension.decompress enforces maxFragmentSize on the INFLATED size of a fragment. If the decompressed output exceeds the configured limit (only when maxFragmentSize > 0), it throws DataFormatException('Inflated fragment size exceeds limit of N bytes'), which is then wrapped into InvalidDataException(1008) by the caller. This protects against decompression bombs.

Solutions

  1. Raise maxFragmentSize when constructing PerMessageDeflateExtension to a value that fits your largest legitimate message after inflation.
  2. If you don't want a limit, set maxFragmentSize to 0 (disables the check) — but only for trusted peers.
  3. Keep the limit for untrusted clients and instead paginate large messages into multiple frames on the sender side.
  4. Log the configured limit versus actual inflated size to tune the threshold.

Example fix

// before
PerMessageDeflateExtension ext = new PerMessageDeflateExtension();
ext.setMaxFragmentSize(1024); // too small for real payloads

// after
PerMessageDeflateExtension ext = new PerMessageDeflateExtension();
ext.setMaxFragmentSize(10 * 1024 * 1024); // 10 MB inflated limit
Defensive patterns

Strategy: validation

Validate before calling

// size-check payload bounds before send on the sender side
if (estimatedInflatedSize > maxFragmentSize) {
    throw new IllegalArgumentException("message exceeds negotiated fragment size limit");
}

Try / catch

try {
    byte[] data = decompressed(frame);
} catch (InvalidDataException e) {
    if (e.getMessage() != null && e.getMessage().contains("exceeds limit")) {
        logger.warn("decompression bomb attempt or limit too low");
    }
    webSocket.close(1009, "message too big");
}

Prevention

When it happens

Trigger: A compressed frame inflates to more than maxFragmentSize bytes while decompress() loops over decompressor.inflate(). Triggered by receiving a small malicious or legitimately huge compressed payload when a fragment size limit has been set via the extension configuration.

Common situations: Defense-against-zip-bomb limits configured too low for legitimate large messages; attackers sending highly compressible payloads to exhaust memory; default or copied configuration not tuned to the application's real message sizes.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of TooTallNate/Java-WebSocket@afeacbf8c0 (2026-09-09). Data as JSON: /api/errors/57e38caf63585ab4. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/org/java_websocket/extensions/permessage_deflate/PerMessageDeflateExtension.java:273

  }

  private void decompress(ByteBuffer buffer, ByteArrayOutputStream decompressed)
      throws DataFormatException {
    if (buffer.hasArray()) {
      decompressor.setInput(
          buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
    } else {
      byte[] input = new byte[buffer.remaining()];
      buffer.duplicate().get(input);
      decompressor.setInput(input);
    }
    byte[] chunk = new byte[TRANSFER_CHUNK_SIZE];
    while (!decompressor.finished()) {
      int length = decompressor.inflate(chunk);
      if (length > 0) {
        decompressed.write(chunk, 0, length);
        if (maxFragmentSize > 0 && maxFragmentSize < decompressed.size()) {
          throw new DataFormatException(
              "Inflated fragment size exceeds limit of " + maxFragmentSize + " bytes");
        }
      } else {
        break;
      }
    }
  }

  @Override
  public void encodeFrame(Framedata inputFrame) {
    // RFC 7692: PMCEs operate only on data messages.
    if (!(inputFrame instanceof DataFrame)) {
      return;
    }

    // compression is only applicable if it was started on the first fragment
    if (!isCompressing && inputFrame instanceof ContinuousFrame) {
      return;

View on GitHub (pinned to afeacbf8c0)