How LiteParse Handles Encrypted PDF Files: Password Flow and Error Handling

LiteParse handles encrypted PDF files by passing an optional password from LiteParseConfig through its Rust core to PDFium's FPDF_LoadDocument API, returning explicit PasswordRequired or InvalidPassword errors when credentials are missing or wrong.

LiteParse, the Rust-based document parser in the run-llama/liteparse repository, delegates all encrypted PDF decryption to the underlying PDFium library. By exposing a single password field in LiteParseConfig, the project unifies password handling across its CLI, Node.js, Python, and native Rust interfaces. This guide walks through the exact code path—from user configuration to PDFium's C API—that enables LiteParse to handle encrypted PDF files securely and consistently.

Password Configuration in LiteParseConfig

The entry point for encrypted PDF support is crates/liteparse/src/config.rs. Here, the LiteParseConfig struct declares the password as an optional string:

pub password: Option<String>

When a user supplies a password through the CLI, a language binding, or the direct Rust API, the value is stored in this field. Because the type is Option<String>, calling code can cleanly represent both password-protected and unprotected documents without separate code paths.

Forwarding Passwords to PDFium via the Rust Core

Once configuration is complete, crates/liteparse/src/parser.rs forwards the credential deeper into the stack. The parser invokes extract::load_document_from_input—a helper defined in crates/liteparse/src/extract.rs—and passes self.config.password.as_deref(), which collapses the stored value into an Option<&str>.

The PDFium wrapper in crates/pdfium/src/library.rs receives this optional reference and calls either pdfium::Pdfium::load_document or load_document_from_bytes. These Rust methods pass the password pointer directly to PDFium's C function FPDF_LoadDocument. If the user did not supply a password, LiteParse sends a null pointer, allowing PDFium to treat the document as unprotected or fail with an encrypted-file error.

Error Handling for Encrypted PDF Files in LiteParse

PDFium signals decryption failures through two specific error variants defined in crates/pdfium/src/error.rs:

  • PdfiumError::PasswordRequired — The PDF is encrypted and password is None.
  • PdfiumError::InvalidPassword — A password was supplied but does not unlock the document.

LiteParse propagates these errors up to the caller unchanged. In crates/liteparse/src/main.rs, the CLI catches them and emits a user-friendly message, making it easy for interactive applications to prompt for corrected credentials.

Rendering and Converting Password-Protected PDFs

Handling encrypted PDF files in LiteParse is not limited to text extraction. The crates/liteparse/src/conversion.rs and crates/liteparse/src/render.rs modules also accept the same Option<&str> password argument. This design lets users convert or render encrypted PDFs to images without pre-decrypting the file or invoking separate tooling.

Parsing Encrypted PDFs in LiteParse: Code Examples

LiteParse exposes the password parameter consistently across every interface.

Command Line Interface

The Rust binary defined in crates/liteparse/src/main.rs adds a --password <STRING> flag that populates LiteParseConfig before parsing begins:

liteparse input.pdf --output json --password "mySecret123"

Node.js and TypeScript

The Node.js wrapper forwards the password field from its options object to the Rust core, as implemented in packages/node/src/lib.ts:

import { LiteParse } from "liteparse";

const parser = new LiteParse({
  password: "mySecret123",
  output: "json"
});

const result = await parser.parseFile("encrypted.pdf");
console.log(result);

Python

In packages/python/liteparse/parser.py, the Python binding maps the password argument onto the same Rust configuration struct:

from liteparse import LiteParse

parser = LiteParse(password="mySecret123", output="json")
result = parser.parse_file("encrypted.pdf")
print(result)

Direct Rust API

You can construct LiteParseConfig explicitly in Rust, supplying password as Some(String):

use liteparse::{LiteParse, LiteParseConfig};

let cfg = LiteParseConfig {
    password: Some("mySecret123".to_string()),
    ..Default::default()
};

let parser = LiteParse::new(cfg);
let result = parser.parse_path("encrypted.pdf")?;
println!("{:?}", result);

Summary

Frequently Asked Questions

What happens if I try to parse an encrypted PDF without a password?

LiteParse aborts the operation and returns PdfiumError::PasswordRequired. The CLI in crates/liteparse/src/main.rs surfaces this as a readable error so you can retry with the --password flag.

Can LiteParse render or convert password-protected PDFs?

Yes. According to the source code in crates/liteparse/src/render.rs and crates/liteparse/src/conversion.rs, both rendering and conversion utilities accept the same Option<&str> password argument. This means LiteParse can handle encrypted PDF files during image generation or format conversion without extra pre-processing steps.

How does the password travel from the CLI to PDFium?

The --password value is stored in LiteParseConfig inside crates/liteparse/src/config.rs. crates/liteparse/src/parser.rs forwards it to extract::load_document_from_input in crates/liteparse/src/extract.rs, and the PDFium wrapper in crates/pdfium/src/library.rs passes the pointer to FPDF_LoadDocument. This creates a direct, unmodified pipeline from user input to the native decryption API.

Does LiteParse distinguish between missing and incorrect passwords?

Yes. PDFium emits PdfiumError::PasswordRequired when no password is provided for an encrypted file, and PdfiumError::InvalidPassword when the supplied string fails to unlock the document. Both variants are defined in crates/pdfium/src/error.rs and propagated to the caller without modification.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →