opendataloader-project/opendataloader-pdf · error · EncryptedTaggedPdfNotSupportedException
'{}' is encrypted; tagged-pdf conversion is not supported fo
Error message
'{}' is encrypted; tagged-pdf conversion is not supported for encrypted documents. What it means
AutoTaggingProcessor.createTaggedPDF() checks the PDF document's trailer dictionary for an Encrypt entry before attempting to add accessibility tags. Encrypted PDFs cannot be tagged because the structure tree modifications would require decrypting and re-encrypting content streams, which this library does not support. The custom EncryptedTaggedPdfNotSupportedException exception makes the failure mode explicit and distinguishable from generic IOExceptions.
Source
Thrown at java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/processors/AutoTaggingProcessor.java:110
COSDocument cosDocument = document.getDocument();
PDCatalog catalog = document.getCatalog();
COSObject structTreeRoot = createStructTreeRoot(catalog, cosDocument, document);
createStructureTreeElements(document, contents, structTreeRoot, cosDocument);
if (isPDF2_0) {
updateDestinationsToStructureDestinations(document, catalog, cosDocument);
}
updatePages(document, cosDocument);
createParentTree(cosDocument, structTreeRoot);
cosDocument.getTrailer().removeKey(ASAtom.ENCRYPT);
}
/**
* Tag a PDF document and save to disk. Existing behavior preserved.
*/
public static synchronized void createTaggedPDF(File inputPDF, String outputFolder, PDDocument document, List<List<IObject>> contents) throws IOException {
COSObject encrypt = document.getDocument().getTrailer().getEncrypt();
if (encrypt != null && !encrypt.empty()) {
throw new EncryptedTaggedPdfNotSupportedException(
"'" + inputPDF.getName() + "' is encrypted; tagged-pdf conversion is not supported for encrypted documents.");
}
tagDocument(document, contents, null);
String outputFileName = outputFolder + File.separator +
FileUtils.getBaseName(inputPDF.getName()) + "_tagged.pdf";
document.saveAs(outputFileName);
LOGGER.log(Level.INFO, "Created {0}", outputFileName);
}
private static void updatePages(PDDocument document, COSDocument cosDocument) throws IOException {
for (OperatorStreamKey operatorStreamKey : structParents.keySet()) {
structParentsIntegers.put(operatorStreamKey, currentStructParent++);
}
List<PDPage> rawPages = document.getPages();
for (int pageNumber = 0; pageNumber < rawPages.size(); pageNumber++) {
PDPage page = rawPages.get(pageNumber);
if (isPDF2_0) {
updateAdditionalAction(page.getObject(), cosDocument, document);View on GitHub (pinned to a7789b8e77)
Solutions
- Decrypt the PDF before processing: load it with the password via PDDocument.load(file, password), then save it unencrypted with document.setAllSecurityToBeRemoved(true) before calling createTaggedPDF.
- Skip encrypted documents in batch processing by catching EncryptedTaggedPdfNotSupportedException and logging a warning.
- Use a tool like qpdf to remove encryption: `qpdf --decrypt input.pdf output.pdf`.
Example fix
// before: encrypted PDF throws and stops the batch
AutoTaggingProcessor.createTaggedPDF(inputPDF, outputFolder, document, contents);
// after: decrypt before tagging, or skip gracefully
COSObject encrypt = document.getDocument().getTrailer().getEncrypt();
if (encrypt != null && !encrypt.empty()) {
// Option A: decrypt if password is known
document.setAllSecurityToBeRemoved(true);
// Option B: skip encrypted documents
// LOGGER.warning("Skipping encrypted PDF: " + inputPDF.getName());
// continue;
}
AutoTaggingProcessor.createTaggedPDF(inputPDF, outputFolder, document, contents); Defensive patterns
Strategy: try-catch
Validate before calling
// Check for encryption before calling createTaggedPDF
COSObject encrypt = document.getDocument().getTrailer().getEncrypt();
boolean isEncrypted = encrypt != null && !encrypt.empty();
if (isEncrypted) {
// Decrypt if password is known, or skip
document.setAllSecurityToBeRemoved(true);
// Re-save to apply decryption
File tempFile = File.createTempFile("decrypted", ".pdf");
document.save(tempFile);
document = PDDocument.load(tempFile);
} Type guard
public static boolean isEncrypted(PDDocument document) {
COSObject encrypt = document.getDocument().getTrailer().getEncrypt();
return encrypt != null && !encrypt.empty();
} Try / catch
try {
AutoTaggingProcessor.createTaggedPDF(inputPDF, outputFolder, document, contents);
} catch (EncryptedTaggedPdfNotSupportedException e) {
// Option A: decrypt and retry if password is known
document.setAllSecurityToBeRemoved(true);
File temp = File.createTempFile("decrypted-", ".pdf");
document.save(temp);
try (PDDocument decrypted = PDDocument.load(temp)) {
AutoTaggingProcessor.createTaggedPDF(inputPDF, outputFolder, decrypted, contents);
}
// Option B: skip encrypted documents in batch processing
// LOGGER.warning("Skipping encrypted PDF: " + inputPDF.getName());
} Prevention
- Check isEncrypted(document) before calling createTaggedPDF in batch processing.
- Pre-decrypt PDFs with qpdf --decrypt in a preprocessing step.
- Catch EncryptedTaggedPdfNotSupportedException specifically — it extends a custom exception, not IOException.
- Load encrypted PDFs with the password: PDDocument.load(file, password) then setAllSecurityToBeRemoved(true).
- Filter encrypted PDFs out of tagged-pdf output format requests at the CLI/batch level.
When it happens
Trigger: Calling AutoTaggingProcessor.createTaggedPDF(inputPDF, outputFolder, document, contents) where the PDDocument was loaded from a PDF whose trailer dictionary contains a non-empty Encrypt COS object. The check is `document.getDocument().getTrailer().getEncrypt()` returning a non-null, non-empty COSObject. This happens with both owner-password and user-password encrypted PDFs.
Common situations: Processing a batch of PDFs where some are password-protected (even with an empty user password); tagged-pdf output format requested (--format tagged-pdf) on a document that has DRM or permissions encryption; a PDF signed with digital signatures that include encryption; scanned documents from a copier that applies encryption by default.
Related errors
AI-assisted analysis of opendataloader-project/opendataloader-pdf@a7789b8e77 (2026-08-14).
Data as JSON: /api/errors/882cbbab22f86142.
Report an issue: GitHub.