BASALT · JOURNAL

Your redacted PDF still shows the text when you copy it. Here is why

2026-08-07 · redacted pdf still shows text

If your redacted PDF still shows text when you select and copy from it, the black mark on the page is a drawing instruction and the words underneath are untouched data. Nothing deleted them, so any tool that reads the file instead of the picture hands them back in full.

This is not a defect in your PDF reader. It is the format behaving exactly as specified, and it means the document you were about to send out is not redacted at all.

Why a redacted PDF still shows text

A PDF page is a small program. The content stream is an ordered list of operators: select a font, set the text matrix, show a string of glyphs with Tj or TJ, set a fill color, define a rectangular path, fill it.

A viewer executes that list top to bottom and paints as it goes, so anything drawn later covers anything drawn earlier. That is why a filled black rectangle emitted after a line of text hides that line on screen.

The rectangle never touched the text operators. The character codes are still sitting in the arguments to Tj and TJ, at their original coordinates. Extraction walks those operators directly and ignores painting order, so it returns the words as though no box existed.

The rendered page is the output of a computation. The file is the source. A mark placed on the output changes nothing in the source.

The box is often not even part of the page

In many cases the rectangle is not in the content stream at all. Markup tools in Preview, in Mail, and in most annotation-first apps create an annotation object: an entry in the page's /Annots array holding a rectangle, a color, and an appearance stream.

Annotations were designed to be removable. A square annotation used as a redaction is a comment shaped like a rectangle, and any tool that deletes comments deletes it, revealing intact text underneath. That is the entire reason a black box over text is not a redaction.

Copy and paste is only the easiest way out

Selecting text is the fastest way to catch this, and it is far from the only route back to the content.

Scanned documents almost always carry an OCR text layer: invisible glyphs drawn in text rendering mode 3, positioned to sit exactly over the picture of the words so the file is searchable. Cover the image with a box and that invisible layer is still fully extractable, which is why redacting a scanned PDF needs the OCR layer handled explicitly.

/ActualText and /Alt entries hold a plain text equivalent of a marked content span for accessibility. A name can be gone from the visible glyph run and still present in /ActualText, where screen readers and extraction tools will find it.

Then there is the update chain. PDF permits incremental updates, where a new revision is appended and the earlier bytes stay in place with an older cross reference table pointing at them. Save your redaction that way and the pre-redaction page is physically inside the document you sent.

Confirming it in a terminal

The check has to read the file, not the rendering. Install Poppler and qpdf with Homebrew.

pdftotext -layout redacted.pdf - | grep -i "smith"

If the name comes back, the text is in the content stream. A clean result is not conclusive, because extraction depends on the font's /ToUnicode map and a subset font without one can hold the original character codes while producing nothing readable. Expand the structure and read it directly.

qpdf --qdf --object-streams=disable redacted.pdf expanded.pdf
strings expanded.pdf | grep -i "smith"

Count the revisions in the file, since more than one end-of-file marker means earlier generations are still present.

strings redacted.pdf | grep -c "%%EOF"

Then check the carriers that are never on a page, since exiftool -a -u -g1 redacted.pdf reads both the information dictionary and the XMP packet, and pdfdetach -list redacted.pdf lists embedded files.

A fuller version of this sequence, including image extraction and layer checks, is in how to verify a PDF redaction.

How to remove the text for real

Proper redaction is a content stream edit. The text-showing operators are parsed into individual glyph runs with real page positions, accounting for the text matrix, font size, horizontal scaling, character and word spacing, and the kerning adjustments inside a TJ array. Because one TJ array usually holds a whole line, the operation is per glyph.

The covered glyphs are excised and the surviving glyphs are re-emitted at their original positions, so a partially redacted line still renders where it did before. Where the sensitive content is pixels rather than glyphs, the pixel data under the mark must be overwritten and the image re-encoded, otherwise the original DCTDecode stream is extractable whole.

The result is then written as a single generation with a fresh cross reference table rather than appended as an incremental update, and the non-page carriers are cleared in the same pass: the information dictionary, the XMP packet, embedded files, hidden optional content groups, annotation values, and stale thumbnails. See what a PDF still carries after you think you cleaned it for the full inventory.

Frequently asked questions

Why does my redacted PDF still show text when I copy it?

Because the redaction only drew a rectangle over the words instead of removing them from the page's content stream. The text-showing operators still hold the original character codes, and copy and paste reads those operators directly rather than looking at what is painted on top. The visual result and the file contents are two different things, and only the file contents matter.

Does flattening a PDF fix a failed redaction?

No. Flattening merges annotations into the page content so the black box can no longer be deleted as a separate object, but it does not touch the text operators underneath. The words remain extractable by any parser. Flattening is a useful step for form values and stamp appearances, and it is not a redaction technique.

Can I just print to PDF to remove the hidden text?

Printing to PDF often drops the selectable text under a mark, but it is unreliable as a redaction method. Some drivers preserve the text layer, OCR layers can survive, and the process usually degrades the document to an image, which destroys searchability and accessibility.

How do I know if the black box is an annotation or part of the page?

Run qpdf --qdf --object-streams=disable file.pdf expanded.pdf and look for an /Annots array on the page along with a /Square or /Redact subtype dictionary near the rectangle coordinates. If the box appears there, it is an annotation and can be deleted in one operation. If it exists only as fill operators inside the content stream, it was flattened or drawn into the page.

Why does the text disappear from copy and paste but still show up in search?

Search and copy use different paths through the file, and a viewer may index the OCR layer, /ActualText entries, or form field values that its selection code does not expose. This mismatch is a strong signal that the content was covered rather than removed. Treat any recovery route as proof the redaction failed, no matter which feature surfaced it.

Is my PDF safe if pdftotext returns nothing?

Not necessarily. pdftotext maps glyphs to characters using the font's /ToUnicode table, and a subset font with a missing or incorrect map can hold the original character codes while producing empty or garbled output. Confirm by expanding the file with qpdf and reading the content stream, and by extracting the embedded images to check for pixels you thought were covered.

Do I need to redo the redaction from the original file?

Yes, in almost every case. Once a document has been saved with a cosmetic mark, the safest path is to go back to the source file and redact it properly, because a repaired copy can still carry earlier revisions in its incremental update chain. Working from the original also avoids inheriting metadata and thumbnails generated during the failed attempt.

Will the recipient actually notice the text is still there?

Assume yes. Recovering covered text requires no specialist software, since selecting and copying, dragging the file into a text editor, or opening it in a different viewer is enough. Published documents have been unredacted this way by readers who were not looking for anything in particular, which is why the check belongs before the file leaves your machine.

Doing it in Basalt

Basalt excises text from the content stream glyph by glyph, re-emits the surviving glyphs in place, destroys and re-encodes image pixels under a mark, and writes the result as a single generation so no earlier revision remains recoverable. Before anything is saved, a verifier re-opens the produced bytes with an independent parser and proves the content is gone, and if it cannot prove that, no file is written at all and it tells you why. The Inspector reports separately on what a document still carries off-page: metadata, XMP, embedded files, hidden layers, OCR text, JavaScript, and saved generations. The engine has no network entitlement, enforced by macOS at the code signature level, so documents never leave your Mac, and every tool writes a new file rather than modifying the original. It is $29 once, lifetime, up to three Macs, free for 24 hours.

Redaction that proves itself

Basalt destroys the content you mark, then re-opens the file it wrote and proves the content is gone before it saves anything. Your documents never leave your Mac.

DOWNLOAD BASALT 2.3.0 BUY $29 FREE FOR 24 HOURS · MACOS 13+