{"record":{"id":"7c7bd4c96cfa1277","repo":"opendataloader-project/opendataloader-pdf","slug":"is-not-a-valid-pdf-file-corrupted-or-truncat","errorCode":null,"errorMessage":"'{}' is not a valid PDF file (corrupted or truncated content).","messagePattern":"'(.+?)' is not a valid PDF file \\(corrupted or truncated content\\)\\.","errorType":"validation","errorClass":"InvalidPdfFileException","httpStatus":null,"severity":"error","filePath":"java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/processors/DocumentProcessor.java","lineNumber":636,"sourceCode":"     */\n    public static void preprocessing(String pdfName, Config config) throws IOException {\n        LOGGER.log(Level.INFO, () -> \"File name: \" + pdfName);\n        validateTempDirWritable();\n        validatePdfMagicNumber(pdfName);\n        updateStaticContainers(config);\n        PDDocument pdDocument;\n        try {\n            pdDocument = new PDDocument(pdfName);\n        } catch (InvalidPasswordException pw) {\n            // Encrypted PDFs are not a content-validity failure — let the\n            // password-handling branch in callers (e.g. CLIMain) take over.\n            throw pw;\n        } catch (IOException cause) {\n            // Magic number was present, so the user expected a real PDF, but\n            // veraPDF could not parse the document (truncated download, body\n            // corruption, missing xref). Surface a friendly message instead\n            // of letting the raw veraPDF IOException leak as a stack trace.\n            throw new InvalidPdfFileException(\n                \"'\" + displayName(pdfName) + \"' is not a valid PDF file (corrupted or truncated content).\",\n                cause);\n        }\n        StaticResources.setDocument(pdDocument);\n        GFSAPDFDocument document = new GFSAPDFDocument(pdDocument);\n//        org.verapdf.gf.model.impl.containers.StaticContainers.setFlavour(Collections.singletonList(PDFAFlavour.WCAG_2_2));\n        StaticResources.setFlavour(Collections.singletonList(Objects.equals(pdDocument.getVersion(), 2.0F) ?\n            PDFFlavour.WCAG_2_2_PDF_2_0_HUMAN : PDFFlavour.WCAG_2_2_HUMAN));\n        StaticStorages.setIsFilterInvisibleLayers(config.getFilterConfig().isFilterHiddenOCG());\n        StaticContainers.setDocument(document);\n        if (config.isUseStructTree()) {\n            document.parseStructureTreeRoot();\n            if (document.getTree() != null) {\n                StaticLayoutContainers.setIsUseStructTree(true);\n            } else {\n                StaticLayoutContainers.setIsUseStructTree(false);\n                LOGGER.log(Level.WARNING, \"The document has no structure tree. The 'use-struct-tree' option will be ignored.\");\n            }","sourceCodeStart":618,"sourceCodeEnd":654,"githubUrl":"https://github.com/opendataloader-project/opendataloader-pdf/blob/a7789b8e77dd05e2b8659eb3ea12fc458f80bfb8/java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/processors/DocumentProcessor.java#L618-L654","documentation":"InvalidPdfFileException (a checked IOException subtype) thrown when the %PDF- magic number IS present (it passed validatePdfMagicNumber) but veraPDF's new PDDocument(pdfName) threw a plain IOException while parsing the body. This means the file looks like a PDF at a glance but its internal structure is broken — interrupted download, missing/incorrect xref table, or garbage after the header. The original veraPDF IOException is preserved as getCause(). InvalidPasswordException is deliberately NOT wrapped here; it is rethrown so encrypted-PDF handling in callers takes over.","triggerScenarios":"Calling DocumentProcessor.processFile / extractContents / preprocessing / OpenDataLoaderPDF.processFile, or AutoTagger.tag, on a file whose first 1024 bytes contain %PDF- but whose body new PDDocument() cannot parse (throws IOException that is not InvalidPasswordException).","commonSituations":"A download was interrupted leaving a truncated file with a valid header. A file was transferred in text mode corrupting binary bytes. A malformed PDF from a buggy producer has a broken xref. An attacker/test payload has a real header followed by non-PDF content.","solutions":["Inspect getCause() for the veraPDF parse error — a missing/bad xref, unexpected EOF, or stream decode failure points at the corruption type.","Re-download or re-export the source PDF; verify byte-size and a checksum against the original.","Validate integrity externally with a PDF repair tool (qpdf --check, mutool clean) before re-running.","If this fires on many files from one producer, the producer is emitting non-conformant PDFs — report upstream rather than patching per file."],"exampleFix":"// before: raw IOException leaks as an opaque stack trace\ntry { pdDocument = new PDDocument(pdfName); }\ncatch (IOException e) { /* caller sees veraPDF internals */ }\n// after: the library already wraps it; callers catch the friendly type\ncatch (InvalidPdfFileException e) {\n    log.error(\"{}: {}\", e.getMessage(), e.getCause().getMessage());\n    return Result.badInput(e.getMessage());\n}","handlingStrategy":"validation","validationCode":"// Validate parseability with qpdf before invoking the heavy pipeline:\n//   qpdf --check file.pdf  (exit 0 => structurally ok)\n// Or in-process, rely on the library's own validatePdfMagicNumber equivalent + a try-parse.","typeGuard":"static boolean isInvalidPdfFile(IOException e) {\n    return e instanceof InvalidPdfFileException;\n}","tryCatchPattern":"try {\n    OpenDataLoaderPDF.processFile(pdfName, config);\n} catch (InvalidPdfFileException e) {\n    // header was present but body unparseable\n    reportBadInput(e.getMessage()); // '... corrupted or truncated content.'\n    if (e.getCause() != null) log.debug(\"veraPDF cause\", e.getCause());\n}","preventionTips":["Run qpdf --check (or mutool clean) on ingested PDFs to catch structural corruption before processing.","Verify file size/checksum after downloads to catch truncation.","Catch InvalidPdfFileException specifically rather than generic IOException so you can distinguish bad input from transient I/O."],"tags":["pdf-validation","corrupt-input","verapdf","ioexception","invalidpdffileexception"],"backgroundTag":null,"analyzedSha":"a7789b8e77dd05e2b8659eb3ea12fc458f80bfb8","analyzedAt":"2026-08-14T05:22:03.953Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}