spring-projects/spring-ai · error · IllegalArgumentException

Unreasonable lineLength of %d provided

Error message

Unreasonable lineLength of %d provided

What it means

TextLine's constructor caps line length at 14,400 PDF units — the ISO 32000 recommendation for maximum page dimension — to prevent memory-exhaustion attacks via excessive char allocation. A larger computed lineLength throws IllegalArgumentException.

Source

Thrown at document-readers/spring-ai-pdf-document-reader/src/main/java/org/springframework/ai/reader/pdf/layout/TextLine.java:45

	private static final char SPACE_CHARACTER = ' ';

	private final int lineLength;

	private final char[] line;

	private int lastIndex;

	TextLine(int lineLength) {
		if (lineLength < 0) {
			throw new IllegalArgumentException("Line length cannot be negative");
		}
		else if (lineLength > 14_400) {
			// Cap to a reasonable limit to prevent attack via excessive char allocation
			// below.
			// 14_400 pdf units is the recommendation for the max dimension of a page by
			// ISO 32000
			throw new IllegalArgumentException("Unreasonable lineLength of %d provided".formatted(lineLength));
		}
		this.lineLength = lineLength / ForkPDFLayoutTextStripper.OUTPUT_SPACE_CHARACTER_WIDTH_IN_PT;
		this.line = new char[this.lineLength];
		Arrays.fill(this.line, SPACE_CHARACTER);
	}

	public void writeCharacterAtIndex(final Character character) {
		character.setIndex(this.computeIndexForCharacter(character));
		int index = character.getIndex();
		char characterValue = character.getCharacterValue();
		if (this.indexIsInBounds(index) && this.line[index] == SPACE_CHARACTER) {
			this.line[index] = characterValue;
		}
	}

	public int getLineLength() {
		return this.lineLength;
	}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Pre-validate page dimensions/text scaling with PDFBox before extraction and reject non-compliant pages (max dimension 14,400 units per ISO 32000).
  2. Normalize the PDF with qpdf/ghostscript to clamp extreme coordinates and scales.
  3. Catch IllegalArgumentException and skip/quarantine the document in ingestion pipelines.
  4. Disable layout-aware extraction so TextLine is never constructed for pathological input.
  5. If legitimate oversized pages must be processed, adjust the 14,400 cap in a forked TextLine.

Example fix

// before
List<Document> docs = new PagePdfDocumentReader(resource,
    PagePdfDocumentReader.config().withLayoutEnabled()).get();

// after
try (PDDocument pd = Loader.loadPDF(resource.getFile())) {
    float maxDim = 0;
    for (PDPage p : pd.getPages()) {
        maxDim = Math.max(maxDim, Math.max(p.getMediaBox().getWidth(), p.getMediaBox().getHeight()));
    }
    if (maxDim > 14_400) throw new IllegalArgumentException("page exceeds ISO 32000 max dimension");
}
List<Document> docs = new PagePdfDocumentReader(resource,
    PagePdfDocumentReader.config().withLayoutEnabled()).get();
Defensive patterns

Strategy: validation

Validate before calling

try (PDDocument doc = Loader.loadPDF(file)) {
    for (PDPage page : doc.getPages()) {
        PDRectangle mb = page.getMediaBox();
        if (mb.getWidth() > 14_400 || mb.getHeight() > 14_400)
            throw new IllegalArgumentException(
                "page exceeds ISO 32000 max dimension (14400): " + mb);
    }
}

Try / catch

try {
    List<Document> docs = new PagePdfDocumentReader(resource,
        PagePdfDocumentReader.config().withLayoutEnabled()).get();
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Unreasonable lineLength")) {
        log.warn("Rejecting PDF with oversized line geometry: {}", resource);
        docs = List.of();
    } else throw e;
}

Prevention

When it happens

Trigger: Layout-aware PDF extraction where computed line width from text positions exceeds 14,400 units — e.g. text drawn at enormous X scale, huge font sizes, or content streams placing text far beyond any valid page — reaching the TextLine constructor.

Common situations: Adversarial PDFs crafted to trigger huge allocations (resource-exhaustion); corrupted documents with extreme text matrices; PDFs with oversized user-defined page dimensions from non-compliant generators.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/860cefadf75d7cfa. Report an issue: GitHub.