DEV Community

Pirate Prentice
Pirate Prentice

Posted on

n8n Read/Write Files Node: Read, Write, and Process Local Files in Your Workflows [Free Workflow JSON]

n8n Read/Write Files Node: Read, Write, and Process Local Files in Your Workflows [Free Workflow JSON]

If you're running n8n self-hosted, sooner or later you'll need to read a file from disk, write output to a file, or pass a binary attachment through a workflow. The Read/Write Files from Disk node (and its companion Convert to/from File node) are the tools for that. This guide covers every operation, the most common gotchas, and three production-ready patterns.


What the Node Does

n8n has two nodes for file work on a self-hosted instance:

Node Purpose
Read/Write Files from Disk Read from or write to the server's local filesystem
Convert to/from File Convert n8n item data to a binary file object (or the reverse) — no disk I/O

Cloud / n8n.cloud users: The Read/Write Files node is not available on n8n Cloud because there's no persistent local filesystem. Use the S3 node, Google Drive node, or another cloud storage integration instead.


Read/Write Files from Disk

Operations

Read File(s) From Disk
Reads one or more files and outputs them as binary data.

File Path: /data/reports/monthly.csv
Property Name: data          ← the binary property name on the output item
Enter fullscreen mode Exit fullscreen mode

You can read multiple files by using an expression referencing an input field, or by providing a glob pattern in some versions.

Write File to Disk
Writes binary data from a previous node to a path on disk.

File Path: /data/output/{{ $now.format('yyyy-MM-dd') }}-report.csv
Property Name: data          ← binary property to write
Enter fullscreen mode Exit fullscreen mode

The directory must already exist — n8n will not create intermediate directories.


Convert to/from File

This node doesn't touch the disk. It converts:

  • To File: Takes text/JSON data from an item and converts it into a binary file object (e.g., turn a JSON object into a downloadable .json file or a string into a .txt file).
  • From File: Takes a binary file object and extracts its content into text or JSON item data.

Convert to File — Operation modes

Mode Input Output binary
Move Base64 String to File Base64 string field Binary property
Move Item Data to JSON File Entire item .json binary
Move Item List to CSV Array of items .csv binary

Convert from File — Operation modes

Mode Input binary Output
Extract From ICS .ics calendar file Calendar event fields
Extract From JSON .json binary Parsed JSON item
Extract From ODS/XLS/XLSX Spreadsheet binary Row items
Extract From PDF PDF binary Text + metadata
Move Binary Data to Item Any binary Base64 string field on item

Credential Setup

None required. Both nodes use the n8n process's filesystem permissions. Make sure:

  1. The n8n process user has read/write access to the paths you use.
  2. Your docker-compose.yml or systemd config mounts the correct volumes.

Docker volume mount example:

volumes:
  - /home/user/n8n-files:/data
Enter fullscreen mode Exit fullscreen mode

Then reference /data/output/report.csv in the node, not the host path.


Common Gotchas

Gotcha Fix
Directory doesn't exist Create it manually or add an Execute Command node to mkdir -p /data/output before the write
Permission denied Check that the n8n user owns the directory; in Docker, set user: "1000:1000" in compose
File path with spaces Wrap in quotes in shell commands; n8n handles it fine in node fields
Reading a file that doesn't exist Wrap in an Error Trigger or use Continue On Fail to handle gracefully
Writing overwrites silently n8n does not warn — use a timestamp in the filename to avoid collisions
Large files crash execution Stream large files in chunks using Execute Command + split; n8n loads entire file into memory
Cloud users getting "node not available" Read/Write Files is self-hosted only; use S3/Drive instead
Binary property name mismatch The property name in Read must match the name consumed by the next node (e.g., EmailSend expects attachment)

Three Production Patterns

Pattern 1: Daily CSV Report — Write to Disk

Trigger → fetch data from DB/API → Convert to File (CSV) → Write File to Disk → Email attachment.

{
  "name": "Daily CSV Report to Disk",
  "nodes": [
    {
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "parameters": {
        "rule": { "interval": [{ "field": "cronExpression", "expression": "0 7 * * *" }] }
      },
      "position": [0, 0]
    },
    {
      "name": "Fetch Data",
      "type": "n8n-nodes-base.httpRequest",
      "parameters": {
        "url": "https://api.example.com/sales/today",
        "responseFormat": "json"
      },
      "position": [200, 0]
    },
    {
      "name": "Convert to CSV",
      "type": "n8n-nodes-base.convertToFile",
      "parameters": {
        "operation": "csv",
        "binaryPropertyName": "report"
      },
      "position": [400, 0]
    },
    {
      "name": "Write to Disk",
      "type": "n8n-nodes-base.readWriteFile",
      "parameters": {
        "operation": "write",
        "fileName": "/data/reports/sales-{{ $now.format('yyyy-MM-dd') }}.csv",
        "dataPropertyName": "report"
      },
      "position": [600, 0]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Pattern 2: Process Incoming Files — Read, Parse, Store

Watch directory → Read file → Convert from File (CSV/JSON) → Upsert to DB → Archive file.

Use case: a partner drops a CSV into /data/incoming/ each night; your workflow reads, parses rows, and upserts them to Postgres.

Schedule Trigger (every 5 min)
  → Execute Command: ls /data/incoming/*.csv
  → IF: stdout not empty
      → Read File from Disk: /data/incoming/{{ $json.filename }}
      → Convert from File: Extract From CSV (or JSON)
      → Postgres: Upsert rows
      → Execute Command: mv /data/incoming/{{ $json.filename }} /data/archive/
Enter fullscreen mode Exit fullscreen mode

Pattern 3: PDF Ingestion Pipeline

HTTP webhook receives a PDF upload → Save to disk → Extract text → Send to AI → Store result.

Webhook (receives binary PDF)
  → Write File to Disk: /data/pdfs/{{ $now.toMillis() }}.pdf
  → Convert from File: Extract From PDF
  → OpenAI / Claude: Summarize extracted text
  → Airtable: Store summary + source filename
Enter fullscreen mode Exit fullscreen mode

This keeps the raw PDF on disk for audit while routing the extracted text through your AI pipeline.


Free Workflow JSON

Here's the daily CSV report pattern as importable JSON — paste into n8n → Import from JSON:

{
  "name": "op: Daily CSV Report Writer",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [{ "field": "cronExpression", "expression": "0 7 * * 1-5" }]
        }
      },
      "name": "Every Weekday 7am",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.1,
      "position": [240, 300],
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    },
    {
      "parameters": {
        "url": "https://httpbin.org/json",
        "options": {}
      },
      "name": "Fetch Sample Data",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [460, 300],
      "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
    },
    {
      "parameters": {
        "operation": "csv",
        "binaryPropertyName": "report",
        "options": {}
      },
      "name": "Convert to CSV",
      "type": "n8n-nodes-base.convertToFile",
      "typeVersion": 1,
      "position": [680, 300],
      "id": "c3d4e5f6-a7b8-9012-cdef-123456789012"
    },
    {
      "parameters": {
        "operation": "write",
        "fileName": "=/data/reports/report-{{ $now.format('yyyy-MM-dd') }}.csv",
        "dataPropertyName": "report",
        "options": {}
      },
      "name": "Write to Disk",
      "type": "n8n-nodes-base.readWriteFile",
      "typeVersion": 1,
      "position": [900, 300],
      "id": "d4e5f6a7-b8c9-0123-defa-234567890123"
    }
  ],
  "connections": {
    "Every Weekday 7am": { "main": [[{ "node": "Fetch Sample Data", "type": "main", "index": 0 }]] },
    "Fetch Sample Data": { "main": [[{ "node": "Convert to CSV", "type": "main", "index": 0 }]] },
    "Convert to CSV": { "main": [[{ "node": "Write to Disk", "type": "main", "index": 0 }]] }
  }
}
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  • Read/Write Files from Disk is self-hosted only — cloud users need S3/Drive
  • Convert to/from File handles format conversion (CSV, JSON, PDF, XLSX) without touching the disk
  • Always pre-create directories; n8n won't make them for you
  • Use timestamps in filenames to avoid silent overwrites
  • For large files, stream via Execute Command rather than loading fully into memory

Want a complete n8n automation toolkit? The n8n Workflow Starter Pack ($29) includes 10 production-ready workflow JSONs for the most common automation patterns — lead capture, Stripe fulfillment, error monitoring, and more. Import and run in minutes.

Top comments (1)

Collapse
 
pirateprentice profile image
Pirate Prentice

Are you running n8n self-hosted and using the Read/Write Files node in production? Would love to hear what directory setups people are using — CSV exports, incoming webhook file drops, or PDF ingestion pipelines.