Attachment Scanning
Attachment scanning reads the text content of Jira issue attachments with the same detection rules used for issue fields and comments.
It is off by default. Enable it per configuration with Scan attachment
contents on Administration -> Scan Configuration, and note that it
requires the SCAN_ATTACHMENTS license feature.
If a scan configuration has attachment scanning turned on but the installed
license does not include SCAN_ATTACHMENTS, the scan still runs normally over
issue fields and comments - attachments are simply not read - and the run
reports:
Attachment scanning is not included in your license; attachments were not scanned.
Formats that are scanned
| Format | Extensions | What is extracted |
|---|---|---|
| Text content | ||
| Word | docx, doc | Body text |
| Excel | xlsx, xls | Cell values across all sheets |
| PowerPoint | pptx, ppt | Slide text |
| OpenDocument | odt, ods, odp | Body text, cell values, slide text |
| Rich Text | rtf | Body text |
| Plain text | txt, log, md | Whole file, as text |
| Delimited text | csv, tsv | Whole file, as text |
| Structured data | json, xml, yaml, yml | Whole file, as text (XML: element text, tags stripped) |
| HTML | html, htm | Rendered text, not markup |
| eml, msg | Headers, body, and attachments one level deep | |
| Archives (one level) | zip, tar, gz | Each entry, parsed as its own format |
| Images (OCR) | png, jpg, jpeg, gif, bmp, tif, tiff, webp | Text recognised by OCR; see Images |
Every attachment's file name is checked against the detection rules,
whether or not its content is one of the formats above. A file called
aws-prod-key.txt.png is flagged on its name alone, whether or not its content
can be read.
A finding produced from an attachment records which attachment it came from, visible on the finding detail page - never the attachment's extracted text.
How a format is decided
The scanner never trusts the media type Jira reports for an attachment; client
software frequently mislabels uploads. Format detection is based on the
attachment bytes, with the file name as a secondary hint, so a .docx uploaded
as application/octet-stream is still read as a Word document.
Images
Screenshots and other bitmap attachments (PNG, JPEG, GIF, BMP, TIFF, WebP) are
read with OCR: Tesseract, with English and German language data (eng+deu),
running as a separate, resource-limited process. The recognised text runs
through the same detection rules as any other attachment text. A finding
produced from it shows the text variant OCR, so a reviewer can tell it came
from an image, which is less certain than text read from a document.
Text is scanned whenever OCR is confident about it, even if the image also needs review: a password legible on a photographed whiteboard still produces a finding.
Some images cannot be judged responsibly by OCR. They are listed on the Manual reviews page, with one of these reasons:
| Reason | Meaning |
|---|---|
PHOTO | Camera photo; may show an ID document, whiteboard or screen |
SCANNED_DOCUMENT | Scanned document; OCR is not reliable enough to trust |
NO_TEXT | No readable text was found in the image |
LOW_CONFIDENCE_TEXT | Text was found but could not be read reliably |
NOT_ANALYZED | The image could not be analysed within the safety limits |
EMBEDDED_IMAGES | The document contains embedded images that were not read |
SCANNED_PAGES | The PDF has pages without a text layer |
An image is a PHOTO when it carries a camera make or model or a GPS position,
and a SCANNED_DOCUMENT when it declares 150 DPI or more (screens report 72, 96
or 144). An image larger than the maximum image size, an animated image, or an
image whose OCR is killed by a resource limit or runs out of time is
NOT_ANALYZED.
A standalone image with a review reason is reported as NEEDS_REVIEW in
attachment coverage, so the scan shows COMPLETED WITH GAPS. A document with
EMBEDDED_IMAGES or SCANNED_PAGES still counts as scanned: its text was read,
and the review is recorded alongside.
Images embedded in documents and archives are not OCR'd. Embedded bitmaps smaller than 20,480 bytes (logos, icons, e-mail signature images) are ignored. A PDF page with fewer than 20 characters of text counts as image-only, so a blank separator page is also listed once; suppress it on Manual reviews and it stays suppressed across rescans.
When Tesseract or its language data is not installed, images are matched by file name only, as before, and each scan that reads attachments carries the warning:
Image analysis is unavailable on this installation; image attachments were matched by file name only.
What is not scanned, and why
| Situation | Reported as | Why |
|---|---|---|
| Images, when image analysis is unavailable on the installation (png, jpg, gif, bmp, tiff, ...) | UNSUPPORTED_FORMAT | Tesseract or its language data is not installed; the scan carries a warning and images are matched by file name only. |
| SVG | UNSUPPORTED_FORMAT | SVG is XML, not a bitmap; it is not OCR'd. |
| Audio and video | UNSUPPORTED_FORMAT | No speech transcription. |
| CAD drawings, standalone font files, PGP/PKCS7/timestamp formats, RSS/Atom feeds, WARC web archives, Apple property lists and iWork documents (Pages, Numbers, Keynote) | UNSUPPORTED_FORMAT | Outside the supported format list. |
| Any other format not listed above | UNSUPPORTED_FORMAT | Decided from the format detected in the file bytes, never from whether the extracted text happened to be empty - an empty .txt file is still scanned normally. |
| Password-protected files | ENCRYPTED | The scanner never attempts to guess or crack a password. |
| A completely empty (0-byte) attachment | CORRUPT | Refused before a format can be detected, whatever the extension. |
| Attachments over the size cap | TOO_LARGE | See Limits. Enforced twice: against the size Jira reports before the download starts, and again against the bytes actually received, so an inaccurate reported size cannot slip an attachment through. |
| Files that fail to parse | CORRUPT | Truncated or malformed input. |
| Files whose readable content exceeds an extraction limit | TRUNCATED | The text captured before the limit is scanned, and the missing coverage is reported. This includes extracted-character, archive-entry, decompressed-byte, and nested-archive depth limits. |
| Files that exceed the parse budget | TIMEOUT | See Limits. |
| Images, and documents whose images cannot be read, that a person has to look at | NEEDS_REVIEW | See Images. The attachment is listed on the Manual reviews page with the specific reason. |
| Attachments deleted between being listed and being downloaded | NOT_FOUND | Expected on long-running scans; not an error. |
Skipped attachments are counted separately from failed ones. A scan that
skips attachments is labelled COMPLETED WITH GAPS. The scan detail page
shows a coverage breakdown beneath the scanned and skipped totals: one row for
each reason in the table above, with the number of attachments it accounts for.
Every reason is listed even when its count is zero, so "no password-protected
files were found" stays distinguishable from "password-protected files were
never checked for". The same breakdown is available from
GET /api/scans/{id}/attachment-coverage, which makes a scan's coverage
something a reviewer can check rather than take on trust.
Nested archives
An archive entry that is itself an archive - a zip inside a zip - is not
opened; extraction goes one level deep only. Everything within that one level
still contributes to the extracted text and findings. The containing
attachment is reported as TRUNCATED, so reviewers can distinguish partial
coverage from a fully scanned attachment.
Limits
| Limit | Default | Environment variable |
|---|---|---|
| Maximum attachment size | 25 MB (26,214,400 bytes) | SCAN_ATTACHMENTS_MAX_DOWNLOAD_BYTES |
| Parse budget per attachment | 60 seconds | SCAN_ATTACHMENTS_PARSE_TIMEOUT |
| Maximum extracted text per attachment | 20,000,000 characters | SCAN_ATTACHMENTS_MAX_EXTRACTED_CHARS |
| Maximum entries read per archive | 1,000 | SCAN_ATTACHMENTS_MAX_ARCHIVE_ENTRIES |
| Maximum decompressed bytes per archive | 50 MB (52,428,800 bytes) | SCAN_ATTACHMENTS_MAX_ARCHIVE_BYTES |
| Attachments parsed at once | 20 | SCAN_ATTACHMENTS_MAX_PARSE_THREADS |
| OCR languages | eng+deu | SCAN_ATTACHMENTS_IMAGES_OCR_LANGUAGES |
| Maximum image size | 40,000,000 pixels | SCAN_ATTACHMENTS_IMAGES_MAX_PIXELS |
| OCR budget per image | 30 seconds | SCAN_ATTACHMENTS_IMAGES_OCR_TIMEOUT |
| OCR memory limit | 536,870,912 bytes | SCAN_ATTACHMENTS_IMAGES_OCR_MAX_MEMORY_BYTES |
| OCR CPU limit | 30 seconds | SCAN_ATTACHMENTS_IMAGES_OCR_CPU_SECONDS |
| Images OCR'd at once | Half the CPU cores, at least 1 | SCAN_ATTACHMENTS_IMAGES_MAX_CONCURRENT_OCR |
| Minimum embedded image size | 20,480 bytes | SCAN_ATTACHMENTS_IMAGES_MIN_EMBEDDED_IMAGE_BYTES |
An attachment that hits an extraction limit is not discarded: the text
captured up to that limit is still scanned. Its coverage reason is
TRUNCATED, and it contributes to the skipped total as well as any findings
produced from the retained text.
Data handling
The detection rules run over the full extracted text of an attachment. That is what attachment scanning is: the same rules that read issue fields and comments read the text inside the file.
The text itself, extracted or recognised by OCR, is held in memory only while that one attachment is being scanned, and is discarded as soon as the rules have run over it. It is never written to the database, never written to logs, and never fed into Pattern Discovery, which only ever looks at issue fields and comments. A finding records an offset and a keyed fingerprint, never the matched text and never the surrounding file content. See Security and Data Handling.
Image bytes are written to a private temporary directory (owner-only permissions) for the duration of OCR and deleted afterwards, whether OCR succeeds, fails or times out. This is the one case in which attachment content touches the disk.
Manual reviews store the attachment file name, issue key and reason, and the reviewer's decision: never image bytes, thumbnails, OCR text or excerpts.
OCR runs in a separate process that receives none of the scanner's secrets (no database, Jira, SMTP or license credentials in its environment) and runs under memory, CPU and time limits. That process's network access is not restricted; Tesseract itself contains no network code.
Planning for it
Attachment scanning is the most expensive thing the scanner does. It downloads
bytes from Jira, so it adds network load on the Jira side and memory pressure
on the scanner. Raise the container's memory before raising
SCAN_ATTACHMENTS_MAX_PARSE_THREADS, and consider running attachment-enabled
scans on a narrower project scope than your routine field-and-comment scans.
OCR is CPU-bound. Give the container CPU before raising
SCAN_ATTACHMENTS_IMAGES_MAX_CONCURRENT_OCR.