https://txtfetch.com/fixes/pdf-extracts-no-text/
Why did my PDF come back with no text at all?
Almost always because there's no text layer to read. It's not a bug in whatever you're using to extract it. Here's how to tell for certain, and the one shape of PDF that fools a naive check.
looks-like
>>> extracted_text
''Your extraction call succeeds and returns nothing. Or, with txtfetch specifically, the call itself fails with a typed extraction_failed error instead of a silent empty string.
why-it-happens
A PDF page is one of two fundamentally different things. It has real text, drawn with font and character-code operators. Or it's a picture of a page, with no text operators at all. pdftotext, pypdf, pdfminer.six, and Apache Tika all read the first case correctly. They all correctly return nothing for the second case. An empty result isn't a parsing failure. It's the honest answer to "is there text here?" That's the answer when the file is a scanned image, a fax, or a flatbed scan saved straight to PDF.
You can run this check yourself: open the PDF and try to select a word with your cursor. If nothing highlights, there's no text layer on that page. No library finds one either, because none exists.
The trickier case is a mixed PDF. Some pages are born-digital and some are scanned. A common example is a digital cover page or coversheet stapled ahead of a faxed body. The document isn't blank overall, so a check that only asks "did we get text back at all" passes. A plain text extractor returns nothing for the scanned pages behind the cover, and nobody notices.
confirm-it
- Drop the file into the PDF text-layer checker. It reads each page individually, so it catches the mixed-document case a check on the whole file misses. Run the PDF text-layer check
- Or just try selecting text in your PDF viewer. No highlight on a given page means no text layer on that page.
fix-it-yourself
OCR it yourself
ocrmypdf adds an invisible, searchable text layer over the existing scanned page images. It's the fastest way to get real text out of a scan without discarding the original page images.
bash
ocrmypdf input.pdf output.pdf
pdftotext output.pdf output.txtConfirm it's genuinely empty before reaching for OCR
A quick byte-count sanity check on the plain-text extraction. It's cheaper than assuming and running OCR on a file that already had text.
bash
pdftotext -layout input.pdf - | wc -cwhat-txtfetch-does
txtfetch runs the plain-text extraction pass first. Then it decides page by page. A page with 10 typed characters or fewer is read with Tesseract OCR, in the same request. A fully scanned PDF comes back as text. Do not use metadata.ocr to confirm it. The flag says false when OCR ran inside a PDF.
Know the one page that fails. A scanned page that also carries a typed footer, page number or stamp of more than 10 characters is not read with OCR. Only the typed text comes back, and the scan is lost. A picture on a typed page is lost for the same reason. Render those pages to PNG files and send the PNG files. Run the PDF text-layer check above first on anything you suspect is mixed. It reports per page. Read /docs/images for the cases we tested.
There's a second safety net on the async path specifically. A request that did NOT pin ?quality= explicitly gets a premium retry automatically. This happens when the Tika baseline for a PDF either needed OCR (metadata.ocr: true) or came back extraction_failed. So an unpinned async request gets a vision-model second read before it gives up. Pinning ?quality=standard opts out of that. A small synchronous upload doesn't take this path at all.
If the document genuinely has no recoverable text after those attempts, txtfetch returns a typed extraction_failed error, not a silent empty success. Failed extractions never count against your monthly quota.
what-it-costs-you-downstream
An empty or partially-empty extracted_text produces a chunk with nothing to embed, silently shrinking that document's presence in the vector store. Or, worse, an ingestion job reports success while a whole document, or the scanned half of one, has quietly never entered the index at all.
faq
- Is an empty PDF extraction always a bug in the library I'm using?
- Almost never. It's the correct answer when the PDF has no text layer at all: a scan, a fax, or a photographed page saved as a PDF. Try selecting text in the PDF viewer itself. If nothing highlights, there's genuinely nothing there for any library to find.
- Why did my mixed PDF come back with SOME text but I know pages are missing?
- txtfetch reads a scanned page with OCR when the page has 10 typed characters or fewer. A cover page and a scanned body both come back. The usual cause of a missing page is a scan with a typed footer or stamp. It has more than 10 characters. Another cause is a picture on a typed page. Render that page to a PNG and send the PNG. Check with the PDF text-layer checker first if you're unsure. It reports per page. Read /docs/images for the tested cases.
- Does txtfetch charge me for a PDF that comes back with no text?
- No. A whitespace-only result returns a typed extraction_failed error. This applies after the OCR retry and, on an unpinned async request, the automatic premium retry. Failed extractions don't count against your monthly document quota.
related-reading
Fix the text you already have.
The free cleaner repairs this damage in your browser. Nothing leaves the page.
Clean up your text →