> Source: https://txtfetch.com/docs/password-protected > Plain-text twin — every page on txtfetch.com has one. https://txtfetch.com/text --- # 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](https://txtfetch.com/tools/pdf-text-check) tells you if a PDF has an encryption entry before you upload it. [The error reference](https://txtfetch.com/docs/errors) 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](https://txtfetch.com/docs/attachments) for the ZIP that has no lock. Read [the PDF page](https://txtfetch.com/extract/pdf) 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 →](https://txtfetch.com/playground) [Get an API key →](https://app.txtfetch.com/signup)