← Back to blog

n8n email attachments: practise saving and reconciling files

Practise handling n8n email attachments in a self-hosted IMAP workflow, with separate file records, collision-resistant paths and manual reconciliation.

An envelope releases n8n email attachments beside separate destination folders and an unfinished save record.

Checked against the cited sources on .

Your n8n email attachments exercise

Build a workflow that receives test messages, saves n8n email attachments to an allowed folder and records which attachments still need attention. This is an editorial exercise: the proposed workflow has not been executed or validated. Its scope is a disposable mailbox and manual recovery of test fixtures.

Use Email Trigger (IMAP) with an IMAP credential and Resolved output, which the documentation describes as including binary attachments. n8n’s mutable master-branch implementation describes this for node versions 2, 2.1 and 2.2. Undated documentation and mutable implementation branches may differ from your installed release.

We think attachment handling is worth practising as a record-reconciliation problem, because a received message and a completed save answer different questions.

Sources: n8n-docs/docs/integrations/builtin/core-nodes/n8n-nodes-base.emailimap.md at main · n8n-io/n8n-docs · GitHub, n8n/packages/nodes-base/nodes/EmailReadImap/v2/EmailReadImapV2.node.ts at master · n8n-io/n8n · GitHub

Prepare the mailbox, folder and records

Prepare self-hosted n8n, a disposable IMAP mailbox, working credentials and a writable absolute destination path. For self-hosted n8n starting with version 2.0, the documented file-access restriction defaults to ~/.n8n-files. Docker paths refer to the container filesystem; prepare a volume mount for a host directory and check your installed version's allowed-directory configuration.

Create Data Tables with the following suggested columns before building the workflow. The attachment ledger uses documented upsert, retrieval and update operations; these column names are an editorial design.

Suggested exercise records
TableColumnsPurpose
receiptstest_case_id, received, attachment_countKeep every test message visible
attachmentsattachment_key, test_case_id, ordinal, original_nameIdentify each attachment
attachmentsintended_path, status, error, attempt_countTrack saving and reconciliation

Sources: Read/Write Files from Disk | Nodes | n8n Docs, skills/skills/n8n-data-tables-official/references/OPERATIONS.md at main · n8n-io/skills · GitHub

Expand messages into attachment items

For your n8n email attachment download exercise, send synthetic messages with explicit, unique test-case identifiers. Use these suggested fixtures and record the expected attachment names before running anything.

Suggested synthetic mailbox fixtures
CaseAttachments
EMPTYNone
SINGLEOne synthetic file
MULTISeveral synthetic files
REPEATTwo files named report.txt

Inspect the actual binary properties in Resolved output. A 2025 n8n Community answer about Gmail demonstrates returning no attachment items when binary data is absent and mapping binary properties into individual items. Adapting that pattern to IMAP is editorial: omit its extension filter, retain message metadata and give each output item one attachment under a consistent binary field, such as attachment.

Write a receipt record before expansion so the empty branch does not hide the zero-attachment case. For n8n email with multiple attachments, assign each fixture attachment a recorded ordinal and preserve that assignment when arranging another attempt. After saving the REPEAT fixture, manually resend its unchanged contents with the original test-case identifier and attachment ordinals to exercise the existing-record check.

Sources: n8n-docs/docs/integrations/builtin/core-nodes/n8n-nodes-base.emailimap.md at main · n8n-io/n8n-docs · GitHub, Getting only the correct attachment - Questions - n8n Community

Choose stable keys and record intended saves

Use this suggested sequence for naming and saving n8n email attachments. The Crypto node supports SHA256 hashing; Read/Write Files from Disk requires a destination path and input binary field. n8n’s mutable master-branch disk-write implementation uses truncating flags with Append disabled, so repeated destination paths risk overwriting files.

  1. Build the attachment key from the assigned test-case identifier and recorded ordinal.
  2. Look up that key before changing its ledger state. Route every existing record through reconciliation before permitting another write.
  3. For a new key, hash it with SHA256; use the hash and a controlled extension inside the allowed folder.
  4. For a new record, upsert the key, metadata, intended path, pending status and attempt_count of zero. Preserve existing paths and counts during recovery unless correcting the deliberately invalid destination.
  5. Disable automatic retries for the exercise’s disk-write node. Immediately before each explicit attachment write invocation, persist pending status and increment that record’s attempt_count once; stop if that update fails. Receipt, lookup, comparison and skipped writes do not increment it.
  6. Write the attachment binary field to the persisted destination with Append disabled.
  7. After success, update the matching record to saved; route the separate error output to record needs-another-attempt and error details.

For example, key REPEAT:1 becomes a SHA256 basename followed by a controlled .txt extension inside your allowed folder. REPEAT:2 produces a separately derived destination despite sharing the original filename. Persist the chosen path and reuse it during recovery. This is collision-resistant naming, not collision-proof or concurrency-safe deduplication.

In our view, original filenames belong in metadata for this exercise; letting them choose filesystem paths adds a distraction before the recovery logic is clear.

Sources: n8n-docs/docs/integrations/builtin/core-nodes/n8n-nodes-base.readwritefile.md at main · n8n-io/n8n-docs · GitHub, n8n/packages/nodes-base/nodes/Files/ReadWriteFile/actions/write.operation.ts at master · n8n-io/n8n · GitHub, n8n-docs/docs/integrations/builtin/core-nodes/n8n-nodes-base.crypto.md at main · n8n-io/n8n-docs · GitHub, skills/skills/n8n-data-tables-official/references/OPERATIONS.md at main · n8n-io/skills · GitHub, skills/skills/n8n-error-handling-official/SKILL.md at main · n8n-io/skills · GitHub

Reconcile unfinished records before another attempt

Two attachment records are checked against a present file and a missing file before another save attempt.
The illustration contrasts a file awaiting a record update with a missing file that needs recovery.

Retrieve pending and needs-another-attempt records. For this editorial reconciliation procedure, inspect each expected file before repeating a write: the file may exist even if the status update failed. Compare its bytes with the retained synthetic attachment. If they match, mark the record saved without rewriting the file or incrementing attempt_count. If the file is absent, manually recover the attachment and retry through the guarded write sequence. Preserve a mismatching file, record the discrepancy and leave the attachment needing attention for investigation.

Apply this check to existing saved records on replay too, before any pending upsert or write. Correlate failures with the attachment key rather than assuming the error output preserves every original field. Use explicit AND matching for compound ledger filters; the reference warns that some versions default to OR, and an update matching nothing does nothing.

Marking mail as read happens when n8n receives it, so unread status cannot prove file-save completion. In n8n’s mutable master-branch IMAP implementation, node versions 2.1 and later offer Fetch Only New Emails based on the last run; leaving a message unread does not establish replay. Recover the binary from the retained test email or manually resend the fixture with its original test-case key.

This design establishes neither exactly-once delivery nor atomic coordination between files and ledger updates. This exercise provides no automatic durable replay or message-retention guarantee.

Sources: n8n-docs/docs/integrations/builtin/core-nodes/n8n-nodes-base.readwritefile.md at main · n8n-io/n8n-docs · GitHub, skills/skills/n8n-data-tables-official/references/OPERATIONS.md at main · n8n-io/skills · GitHub, skills/skills/n8n-error-handling-official/SKILL.md at main · n8n-io/skills · GitHub, n8n-docs/docs/integrations/builtin/core-nodes/n8n-nodes-base.emailimap.md at main · n8n-io/n8n-docs · GitHub, n8n/packages/nodes-base/nodes/EmailReadImap/v2/EmailReadImapV2.node.ts at master · n8n-io/n8n · GitHub

Check completion and explain the remaining gap

Use this editorial checklist as your completion criteria for n8n email attachments, rather than as a validated assessment.

If a check fails, inspect credentials and mailbox selection, actual binary field names, allowed directories, Docker mounts and ledger filter matching. For reflection, explain how you would distinguish an absent file from a completed write whose ledger update failed, and what evidence would justify changing its status.

Sources: n8n-docs/docs/integrations/builtin/core-nodes/n8n-nodes-base.emailimap.md at main · n8n-io/n8n-docs · GitHub, n8n-docs/docs/integrations/builtin/core-nodes/n8n-nodes-base.readwritefile.md at main · n8n-io/n8n-docs · GitHub, Read/Write Files from Disk | Nodes | n8n Docs, skills/skills/n8n-data-tables-official/references/OPERATIONS.md at main · n8n-io/skills · GitHub, skills/skills/n8n-error-handling-official/SKILL.md at main · n8n-io/skills · GitHub

Put this into practice

Hands-on n8n challenges

Pick a challenge and build a working workflow in your own n8n environment, with five progressive tips per challenge.

Try a hands-on challenge

For your team

Custom n8n training programs for one team or department, run on your own n8n instance with your own tools and data.

Training for your team

n8n skills assessment

A free quiz of about 20 minutes: 30 questions in 10 skill areas and a level from Beginner to Expert. On AI Adoption Score, another project by the author of this site.

Get your n8n level