https://txtfetch.com/docs/password-protected/
Do password-protected files come back?
No. A locked PDF is refused, even one that opens without a password. A locked Word or Excel file fails with a different code. A locked ZIP says success and drops the content.
The short answer
No. txtfetch cannot read a locked file. You must unlock the file before you upload it. The API has no password parameter.
A PDF with encryption is refused with a 422 and the code encrypted. This includes a PDF that opens in a viewer with no password, because only its owner password is set. The API looks for the encryption entry before it reads the text.
An encrypted Word or Excel file also fails with a 422. The code is extraction_failed, not encrypted. The message is tika returned 422.
A ZIP with an encrypted file is the worst case. The status is success. The text holds the file name, and the text inside the file is missing. Nothing says so.
Some locks do not matter. A Word file with restricted editing and an Excel file with a protected sheet both come back in full.
The engine is tika-server-standard 3.3.1.
Source: terraform/lambda-layers/build/versions.env (versions.env: TIKA_VERSION), accessed 2026-10-22.
What comes back, case by case
We built one small file for each case. Each file holds a marker word, so you can see what came back. We sent each file to the production API. Every row shows its source. The inputs and the raw responses are in the repo.
| Input | What comes back | Source |
|---|---|---|
| A PDF with only an owner password, RC4 128-bit. It opens in a viewer with no password. Copy and print are locked. | The API refuses it with a 422 and the code encrypted. The text is not returned. Unlock the file first. | Production API probe: POST /v1/extract accessed 2026-10-22 |
| The same PDF with AES 256-bit encryption | Refused with the same 422 and the same code. The cipher does not change the answer. | Production API probe: POST /v1/extract accessed 2026-10-22 |
| A PDF with a user password. A viewer asks for the password. | Refused with the same 422 and the same code. | Production API probe: POST /v1/extract accessed 2026-10-22 |
| A Word file encrypted with a password | Refused with a 422, but the code is extraction_failed and the message is tika returned 422. The code is not encrypted. | Production API probe: POST /v1/extract accessed 2026-10-22 |
| An Excel file encrypted with a password | The same as the Word file: extraction_failed, with the message tika returned 422. | Production API probe: POST /v1/extract accessed 2026-10-22 |
| A Word file with restricted editing. It is not encrypted. | The full text comes back. The restriction is a flag in the file. It does not stop the API. | Production API probe: POST /v1/extract accessed 2026-10-22 |
| An Excel file with a protected sheet. It is not encrypted. | The full text comes back, with the sheet name and the cell value. | Production API probe: POST /v1/extract accessed 2026-10-22 |
| A ZIP with one AES-encrypted file inside | The status is success. The text holds the file name only. The text inside the file is missing, and nothing says so. | Production API probe: POST /v1/extract accessed 2026-10-22 |
| A plain ZIP with the same layout (the control) | The file name and the text inside it both come back. | Production API probe: POST /v1/extract accessed 2026-10-22 |
Real output
Each block is the full response body, as the API sent it. In the JSON, \n is a line break inside the text.
A PDF with only an owner password, RC4 128-bit. It opens in a viewer with no password. Copy and print are locked.
In
owner-only-rc4.pdf
Out
{"status":"error","error":{"code":"encrypted","message":"document is encrypted or password-protected"}}The same PDF with AES 256-bit encryption
In
owner-only-aes.pdf
Out
{"status":"error","error":{"code":"encrypted","message":"document is encrypted or password-protected"}}A PDF with a user password. A viewer asks for the password.
In
user-pw.pdf
Out
{"status":"error","error":{"code":"encrypted","message":"document is encrypted or password-protected"}}A Word file encrypted with a password
In
encrypted.docx
Out
{"status":"error","error":{"code":"extraction_failed","message":"tika returned 422"}}An Excel file encrypted with a password
In
encrypted.xlsx
Out
{"status":"error","error":{"code":"extraction_failed","message":"tika returned 422"}}A Word file with restricted editing. It is not encrypted.
In
edit-restricted.docx
Out
{"status":"success","extracted_text":"PROTECTWORD read-only editing restriction.\n\n\n\n\n","metadata":{"content_type":"application/vnd.openxmlformats-officedocument.wordprocessingml.document","bytes":36640,"chars":47,"ocr":false}}An Excel file with a protected sheet. It is not encrypted.
In
sheet-protected.xlsx
Out
{"status":"success","extracted_text":"Sheet\n\tXLSXWORD\n\n\n","metadata":{"content_type":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","bytes":4942,"chars":18,"ocr":false}}A ZIP with one AES-encrypted file inside
In
aes.zip
Out
{"status":"success","extracted_text":"inner.txt\n","metadata":{"content_type":"application/zip","bytes":200,"chars":10,"ocr":false}}A plain ZIP with the same layout (the control)
In
plain.zip
Out
{"status":"success","extracted_text":"\ninner.txt\nZIPPLAIN inside a zip.\n\n\n","metadata":{"content_type":"application/zip","bytes":138,"chars":36,"ocr":false}}Locked or only restricted
Two words mean two different things. A file that is encrypted needs a password to open. A file that is restricted opens, and the restriction only limits what an editor lets you do.
Restricted editing in Word and a protected sheet in Excel are restrictions. The text is in the file in plain form, and the API reads it. A PDF with an owner password is different. The viewer opens it, but the file holds an encryption entry. The API refuses it for that entry.
Unlock the file first
Unlock the file on your side, then upload the copy. Each script below ran on our test file. We sent the unlocked copy to production. The last block under each script is the response. Unlock only files that you may open.
Unlock a PDF
The script removes the encryption and saves a copy. An owner-only PDF needs no password. A PDF with a user password needs that password. pikepdf is a Python wrapper for qpdf.
Install
pip install pikepdf
Python, saved as unlock_pdf.py. Run: python unlock_pdf.py owner-only-rc4.pdf unlocked.pdf
# Removes the password from a PDF. pikepdf is a Python wrapper for qpdf.
# Run: python unlock_pdf.py locked.pdf unlocked.pdf [password]
# An owner-only PDF needs no password. A user-password PDF needs the user password.
import sys
import pikepdf
src, dst = sys.argv[1], sys.argv[2]
password = sys.argv[3] if len(sys.argv) > 3 else ""
with pikepdf.open(src, password=password) as pdf:
pdf.save(dst, encryption=False)
The API returned, for unlocked.pdf
{"status":"success","extracted_text":"\nPLAINWORD quarterly report page one.\n\n\n","metadata":{"content_type":"application/pdf","bytes":1223,"chars":40,"ocr":false}}Unlock a Word or Excel file
The script decrypts the file with the password and saves a copy. It works for .docx and .xlsx.
Install
pip install msoffcrypto-tool
Python, saved as unlock_office.py. Run: python unlock_office.py encrypted.docx unlocked.docx pw
# Removes the password from a Word or Excel file.
# Run: python unlock_office.py locked.docx unlocked.docx password
import sys
import msoffcrypto
src, dst, password = sys.argv[1], sys.argv[2], sys.argv[3]
with open(src, "rb") as f, open(dst, "wb") as out:
office = msoffcrypto.OfficeFile(f)
office.load_key(password=password)
office.decrypt(out)
The API returned, for unlocked.docx
{"status":"success","extracted_text":"DOCXWORD secret memo body.\n\n\n\n\n","metadata":{"content_type":"application/vnd.openxmlformats-officedocument.wordprocessingml.document","bytes":36599,"chars":31,"ocr":false}}Unpack a ZIP with encrypted files
The script unpacks the ZIP into a folder, with the password. Send the files in the folder, one at a time. The unzip command cannot open AES encryption.
Install
pip install pyzipper
Python, saved as unlock_zip.py. Run: python unlock_zip.py aes.zip folder pw
# Unpacks a ZIP with AES-encrypted members.
# Run: python unlock_zip.py locked.zip folder password
import sys
import pyzipper
src, folder, password = sys.argv[1], sys.argv[2], sys.argv[3]
with pyzipper.AESZipFile(src) as z:
z.setpassword(password.encode())
z.extractall(folder)
The API returned, for folder/inner.txt
{"status":"success","extracted_text":"ZIPWORD inside an encrypted zip.\n","metadata":{"content_type":"text/plain","bytes":32,"chars":33,"ocr":false}}For a PDF with a user password, add the password as the last argument. We ran it with the user password on our test file. The unlocked copy came back as success with the full text.
Find out in code if a file is locked
The function reads the API response. It also reads a ZIP itself, because a locked ZIP returns success. The error reference says to match on the code, not on the message. Here the message is the only way to tell a locked Office file from a failed extraction, so the check is a guess. Tika can return 422 for another reason. We did not test those other causes.
Install
No install. It uses the standard library only.
Python, saved as check_locked.py. Run: python check_locked.py aes.zip response.json
# Says why a file is locked, or "not locked". Standard library only.
# Run: python check_locked.py locked.zip response.json
# response.json is the body the API sent for that file.
import json
import sys
import zipfile
def locked_reason(path, response):
# A ZIP with an encrypted member returns success, so read the ZIP itself.
if path.lower().endswith(".zip"):
with zipfile.ZipFile(path) as z:
if any(info.flag_bits & 0x1 for info in z.infolist()):
return "a ZIP member is encrypted, and its text is missing"
error = response.get("error") or {}
if error.get("code") == "encrypted":
return "an encrypted PDF"
if error.get("code") == "extraction_failed" and error.get("message") == "tika returned 422":
return "an encrypted Word or Excel file, or a file that Tika cannot open"
return None
if __name__ == "__main__":
with open(sys.argv[2]) as f:
print(locked_reason(sys.argv[1], json.load(f)) or "not locked")
It printed, for aes.zip and the response above
a ZIP member is encrypted, and its text is missing
The PDF text check tells you if a PDF has an encryption entry before you upload it. The error reference lists every code the API returns.
What we did not test
We tested files that we uploaded. We did not test a page that txtfetch fetches from a URL. We did not test the old .doc, .xls and .ppt formats with a password. We did not test OpenDocument files with a password. We did not test 7z or RAR archives. We did not test a ZIP with the old ZipCrypto encryption. We sent AES only. We did not test S/MIME or PGP mail, or a DRM-protected EPUB. We did not run the qpdf and 7z command-line tools, so the scripts use their Python equivalents. We make no claim about any of these.
Read Attachments and archives for the ZIP that has no lock. Read the PDF page for the rest of the format.
Frequently asked questions
- Can txtfetch read a password-protected PDF?
- No. The API refuses every PDF that has encryption, with a 422 and the code encrypted. Unlock the PDF first, then upload the copy. The unlock script is on this page.
- My PDF opens with no password. Why does the API refuse it?
- The PDF has an owner password. That password sets limits on copy and print, and a viewer opens the file without it. The file still holds an encryption entry. The API refuses a PDF that has the entry, before it reads the text. We sent two owner-only PDFs, and both came back as encrypted.
- What code does a locked Word or Excel file return?
- extraction_failed, with the message tika returned 422. It does not return the code encrypted. We do not know what else can make Tika return 422, so the message alone does not prove that a file is locked.
- Does a Word file with restricted editing come back?
- Yes. Restricted editing is a flag in the file. It is not encryption. The full text came back in our test.
- Does a protected Excel sheet come back?
- Yes. A protected sheet is a flag, not encryption. The sheet name and the cell value came back in our test.
- Does a ZIP with an encrypted file return an error?
- No. It returns success. The text holds the file name, and the text inside the file is missing. Check the ZIP before you upload, with the check script on this page.
- Can I send the password to the API?
- No. The API has no password parameter. Unlock the file on your side, then upload the copy.
- Does unlocking change the text?
- In our test it did not. The unlocked files came back with the same text as the plain files. Unlock only files that you may open.
- Did you test .doc, .xls, .ppt, ODF, 7z or RAR files?
- No. We tested the files in the table. We did not test the old Office formats, OpenDocument files with a password, 7z or RAR archives, or a ZIP with the old ZipCrypto encryption. We make no claim about them.
Watch it run, then take a key.
The playground replays a real recorded response for every sample document.
Open the playground →