spring-projects/spring-ai · error · IllegalArgumentException
Line length cannot be negative
Error message
Line length cannot be negative
What it means
TextLine's package constructor validates the computed line length before allocating its char buffer. A negative lineLength means upstream PDF layout math produced an invalid (negative) width/position delta, so an IllegalArgumentException is thrown instead of allocating a broken array.
Source
Thrown at document-readers/spring-ai-pdf-document-reader/src/main/java/org/springframework/ai/reader/pdf/layout/TextLine.java:38
/*
* @author Soby Chacko
* @author Tibor Tarnai
*/
class TextLine {
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) {View on GitHub (pinned to 98a7beda4f)
Solutions
- Sanitize the PDF (qpdf --clean / ghostscript rewrite) to fix invalid text positioning before extraction.
- Disable layout-aware extraction (use plain text extraction) to bypass TextLine construction.
- Catch IllegalArgumentException from DocumentReader.get() and skip the offending file.
- Report/fix the upstream coordinate computation if it comes from your own PDF-generating code.
Example fix
// before
List<Document> docs = new PagePdfDocumentReader(badResource,
PagePdfDocumentReader.config().withLayoutEnabled()).get();
// after
List<Document> docs;
try {
docs = new PagePdfDocumentReader(badResource,
PagePdfDocumentReader.config().withLayoutEnabled()).get();
} catch (IllegalArgumentException e) {
docs = List.of(); // or fall back to non-layout extraction
} 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() < 0 || mb.getHeight() < 0)
throw new IllegalArgumentException("negative page dimension: " + mb);
}
} Try / catch
try {
List<Document> docs = new PagePdfDocumentReader(resource,
PagePdfDocumentReader.config().withLayoutEnabled()).get();
} catch (IllegalArgumentException e) {
if (e.getMessage().equals("Line length cannot be negative")) {
log.warn("Skipping PDF with invalid text geometry: {}", resource);
docs = List.of();
} else throw e;
} Prevention
- Validate media box dimensions (non-negative, within ISO 32000 limits) before extraction
- Rewrite generator output so text matrices never produce negative position deltas
- Use non-layout extraction for untrusted documents to bypass TextLine allocation entirely
- Skip-and-log such documents in batch ingestion rather than failing the whole job
When it happens
Trigger: PDF text extraction where a computed line length from text positions (e.g. negative x-position deltas or negative scaling in text matrices) yields a value < 0 passed to the TextLine constructor during writeTextPositionList processing.
Common situations: Malformed PDFs with negative coordinates or bad transformation matrices; files generated by buggy producers; fuzzed/adversarial inputs to ForkPDFLayoutTextStripper.
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
- Unreasonable lineLength of %d provided
- Unreasonable number of lines (%d) computed from content of p
- Unreasonable pdf paragraph depth
- pdf containing circular reference or unreasonable nesting le
- Unknown model provider:
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/b5c73e31c56fabd5.
Report an issue: GitHub.