Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions docs/breaking-changes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
---
title: n8n v2.0 breaking changes
description: Breaking changes coming in version 2.0
contentType: reference
---

# n8n v2.0 breaking changes

This document provides a summary of breaking changes planned for version 2.0 of n8n. These changes improve security, simplify configuration, and remove legacy features.

The release of n8n 2.0 continues n8n's commitment to providing a secure, reliable, and production-ready automation platform. This major version includes important security enhancements and cleanup of deprecated features.

## Behavioural changes

### Return expected sub-workflow data when it contains a wait node

When a workflow calls a subworkflow which contains a wait node, the child workflow incorrectly returns the input items of the wait node to the parent workflow. This behaviour is incorrect. In v2, the parent workflow will receive the data from the end of the subworkflow.

Check failure on line 17 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Vale.Spelling] Did you really mean 'subworkflow'? Raw Output: {"message": "[Vale.Spelling] Did you really mean 'subworkflow'?", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 17, "column": 259}}}, "severity": "ERROR"}

Check failure on line 17 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Vale.Spelling] Did you really mean 'subworkflow'? Raw Output: {"message": "[Vale.Spelling] Did you really mean 'subworkflow'?", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 17, "column": 25}}}, "severity": "ERROR"}

**Migration path:** Review any workflows that call subworkflows and rely on this behaviour.

Check failure on line 19 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Vale.Spelling] Did you really mean 'subworkflows'? Raw Output: {"message": "[Vale.Spelling] Did you really mean 'subworkflows'?", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 19, "column": 52}}}, "severity": "ERROR"}

### Remove nodes whose service has been retired

Check warning on line 21 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [from-write-good.Passive] 'been retired' may be passive voice. Use active voice if you can. Raw Output: {"message": "[from-write-good.Passive] 'been retired' may be passive voice. Use active voice if you can.", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 21, "column": 36}}}, "severity": "WARNING"}

The following nodes are removed, since the service they integrate to has been retired:

Check warning on line 23 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [from-write-good.Passive] 'been retired' may be passive voice. Use active voice if you can. Raw Output: {"message": "[from-write-good.Passive] 'been retired' may be passive voice. Use active voice if you can.", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 23, "column": 74}}}, "severity": "WARNING"}

Check warning on line 23 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [from-write-good.Passive] 'are removed' may be passive voice. Use active voice if you can. Raw Output: {"message": "[from-write-good.Passive] 'are removed' may be passive voice. Use active voice if you can.", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 23, "column": 21}}}, "severity": "WARNING"}

- Spontit node
- crowd.dev node
- Kitemaker node

## Public API

## The public API endpoint `PUT /workflows/{id}` will be changed

Check warning on line 31 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [from-write-good.Passive] 'be changed' may be passive voice. Use active voice if you can. Raw Output: {"message": "[from-write-good.Passive] 'be changed' may be passive voice. Use active voice if you can.", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 31, "column": 55}}}, "severity": "WARNING"}

TODO

## Security

### Block env access from Code Node by default

Check failure on line 37 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Vale.Spelling] Did you really mean 'env'? Raw Output: {"message": "[Vale.Spelling] Did you really mean 'env'?", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 37, "column": 11}}}, "severity": "ERROR"}

n8n will block access to environment variables from the Code node by default to improve security. The default value of `N8N_BLOCK_ENV_ACCESS_IN_NODE` will be changed to `true`.

Check warning on line 39 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [from-write-good.Passive] 'be changed' may be passive voice. Use active voice if you can. Raw Output: {"message": "[from-write-good.Passive] 'be changed' may be passive voice. Use active voice if you can.", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 39, "column": 156}}}, "severity": "WARNING"}

**Migration path:** If you need to access environment variables from Code nodes, set `N8N_BLOCK_ENV_ACCESS_IN_NODE=false` in your environment configuration. However, consider using credentials or other secure methods to pass sensitive data instead.

Check warning on line 41 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [from-write-good.TooWordy] 'However' is too wordy. Raw Output: {"message": "[from-write-good.TooWordy] 'However' is too wordy.", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 41, "column": 158}}}, "severity": "WARNING"}

### Enforce settings file permissions

n8n will enforce strict permissions on configuration files by default, similar to how SSH enforces permissions on SSH keys. Configuration files will be set to `0600` permissions (readable and writable only by the owner).

Check warning on line 45 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [from-write-good.Passive] 'be set' may be passive voice. Use active voice if you can. Raw Output: {"message": "[from-write-good.Passive] 'be set' may be passive voice. Use active voice if you can.", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 45, "column": 150}}}, "severity": "WARNING"}

Check warning on line 45 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [from-write-good.TooWordy] 'similar to' is too wordy. Raw Output: {"message": "[from-write-good.TooWordy] 'similar to' is too wordy.", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 45, "column": 72}}}, "severity": "WARNING"}

**Migration path:** Set `N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true` to test this behavior before v2.0. If your environment doesn't support file permissions (e.g. on Windows), set `N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=false`.

Check warning on line 47 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [n8n-styles.eg] Consider replacing 'e.g' with 'for example' Raw Output: {"message": "[n8n-styles.eg] Consider replacing 'e.g' with 'for example'", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 47, "column": 159}}}, "severity": "WARNING"}

Check failure on line 47 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [from-microsoft.Foreign] Use 'for example' instead of 'e.g. '. Raw Output: {"message": "[from-microsoft.Foreign] Use 'for example' instead of 'e.g. '.", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 47, "column": 159}}}, "severity": "ERROR"}

### Enable Task Runners by default

[Task Runners](/hosting/configuration/task-runners.md) will be enabled by default for improved security and isolation. Code node execution will happen on task runners by default.

Check warning on line 51 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [from-write-good.Passive] 'be enabled' may be passive voice. Use active voice if you can. Raw Output: {"message": "[from-write-good.Passive] 'be enabled' may be passive voice. Use active voice if you can.", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 51, "column": 61}}}, "severity": "WARNING"}

**Migration path:** Set `N8N_RUNNERS_ENABLED=true` to test this behavior before v2.0. Ensure your infrastructure can support task runners. Consider using [external mode](/hosting/configuration/task-runners.md#External_mode) for improved security.

### Remove task runner from `n8nio/n8n` docker image

The task runner will be removed from the main `n8nio/n8n` Docker image for external mode.

**Migration path:** Change the task runner's Docker image from `n8nio/n8n` to `n8nio/runners` if you're running task runners in Docker in external mode.

### Remove Pyodide based Python Code node

The Pyodide-based Python Code node will be removed in favor of the [task runner](/hosting/configuration/task-runners.md) based implementation for better security and performance, which uses native Python. Only [external mode](/hosting/configuration/task-runners.md#External_mode) is supported for Python Code node.

The native Python Code node does not support any of the built-ins, such as `_input` that were available in the Pyodide-based implementation. Dot access notation is not supported either. See [Code node](/integrations/builtin/core-nodes/code-node.md#Python\(Native - beta\)) for more details.

Check failure on line 65 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [from-microsoft.Contractions] Use 'isn't' instead of 'is not'. Raw Output: {"message": "[from-microsoft.Contractions] Use 'isn't' instead of 'is not'.", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 65, "column": 162}}}, "severity": "ERROR"}

Check failure on line 65 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [from-microsoft.Contractions] Use 'doesn't' instead of 'does not'. Raw Output: {"message": "[from-microsoft.Contractions] Use 'doesn't' instead of 'does not'.", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 65, "column": 29}}}, "severity": "ERROR"}

**Migration path:** Configure task runner in external mode to continue using Python in Code nodes. Review any existing Python Code nodes.

### Disable ExecuteCommand and LocalFileTrigger nodes by default

The `ExecuteCommand` and `LocalFileTrigger` nodes will be disabled by default as they pose security risks. These nodes allow arbitrary command execution and file system access.

**Migration path:** If you need to use these nodes, you'll need to explicitly remove them from the list of disabled nodes in your n8n configuration using `NODES_EXCLUDE="[]"`

### Require auth on OAuth callback URLs by default

OAuth callback endpoints will require authentication by default. The default value for `N8N_SKIP_AUTH_ON_OAUTH_CALLBACK` will change from `true` to `false`.

**Migration path:** Test your OAuth integrations with `N8N_SKIP_AUTH_ON_OAUTH_CALLBACK=false` before upgrading to v2.0.

### Set default value for N8N_RESTRICT_FILE_ACCESS_TO

n8n will set a default value for `N8N_RESTRICT_FILE_ACCESS_TO` to restrict where file operations can be performed. This affects the `ReadWriteFile` and `ReadBinaryFiles` nodes. The default value will be `./data` directory within the n8n home folder.

**Migration path:** Review your workflows that use file nodes and ensure they operate within the allowed directories. Configure `N8N_RESTRICT_FILE_ACCESS_TO` explicitly if you need different behavior.

### Change the default value of N8N_GIT_NODE_DISABLE_BARE_REPOS to true

The Git node will disable bare repositories by default for security reasons. The default value of `N8N_GIT_NODE_DISABLE_BARE_REPOS` will change to `true`.

**Migration path:** If you need to work with bare repositories, explicitly set `N8N_GIT_NODE_DISABLE_BARE_REPOS=false` in your environment configuration.

## Data

### Drop MySQL/MariaDB support

n8n will drop support for MySQL and MariaDB as storage backends. Support for these was deprecated in v1.0. PostgreSQL is recommended for better compatibility and long-term support.

**Migration path:** Use the database migration tool to migrate from MySQL/MariaDB to PostgreSQL or SQLite before upgrading to v2.0.

### Remove SQLite legacy driver

The legacy SQLite driver has a lot of issues and will be removed. SQLite's pooling driver will become the default and only SQLite driver. The pooling driver uses WAL mode, single write connection and a pool of read connections. According to our benchmarks it is up to 10x more performant.

Check failure on line 103 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [from-microsoft.Contractions] Use 'it's' instead of 'it is'. Raw Output: {"message": "[from-microsoft.Contractions] Use 'it's' instead of 'it is'.", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 103, "column": 257}}}, "severity": "ERROR"}

**Migration path:** The `sqlite-pooled` driver will automatically become the default. It can already be setting `DB_SQLITE_POOL_SIZE` to a value higher than 0. The default will become `2`.

### Disable binary data in-memory mode by default

The `N8N_DEFAULT_BINARY_DATA_MODE` `default` mode (which keeps execution binary data in-memory) will be removed. Filesystem mode will become the default for better performance and stability.

**Migration path:** Filesystem mode will automatically become the default. Ensure your n8n instance has appropriate disk space for storing binary data. See the [binary data configuration](/hosting/configuration/environment-variables/binary-data/) for more details.

## Configuration & Environment

### Upgrade dotenv

Check failure on line 115 in docs/breaking-changes.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Vale.Spelling] Did you really mean 'dotenv'? Raw Output: {"message": "[Vale.Spelling] Did you really mean 'dotenv'?", "location": {"path": "docs/breaking-changes.md", "range": {"start": {"line": 115, "column": 13}}}, "severity": "ERROR"}

n8n automatically loads environment configuration from a `.env` file if one is given using the `dotenv` library. n8n will upgrade the `dotenv` library from `8.6.0` to the latest version, which may include breaking changes in how `.env` files are parsed. The biggest breaking changes are:
- Backtick support ([#615](https://github.com/motdotla/dotenv/pull/615)): If you had values containing the backtick character, please quote those values with either single or double quotes.
- Multiline support
- `#` marks the beginning of a comment


**Migration path:** If using a `.env` file, review the [dotenv changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md) and ensure your `.env` file is compatible with the new version.

### Remove n8n --tunnel option

The `n8n --tunnel` command-line option will be removed.

**Migration path:** If you're using the `--tunnel` option for development or testing, use alternative tunneling solutions like ngrok, localtunnel, or Cloudflare Tunnel.

### Remove QUEUE_WORKER_MAX_STALLED_COUNT

The `QUEUE_WORKER_MAX_STALLED_COUNT` environment variable and the Bull retry mechanism for stalled jobs will be removed as it causes more confusion and incorrect behavior than it provides value.

**Migration path:** Remove this environment variable from your configuration. The automatic retry mechanism for stalled jobs will no longer be available.

## CLI & Workflow

### Remove CLI command operation to activate all workflows

The CLI command `update:workflow --all --active=true` to activate all workflows will be removed as it can cause unintended consequences in production environments.

**Migration path:** Activate workflows individually or in controlled batches using the API or UI.

## Reporting issues

If you encounter any issues during the process of updating to n8n 2.0, please seek help in the community [forum](https://community.n8n.io/).
1 change: 1 addition & 0 deletions nav.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ nav:
- Release notes:
- 1.x: release-notes.md
- 0.x: release-notes/0-x.md
- v2.0 breaking changes: 2-0-breaking-changes.md
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Bug

The nav.yml entry for "v2.0 breaking changes" points to 2-0-breaking-changes.md, but the actual file is breaking-changes.md. This filename mismatch results in a broken navigation link.

Fix in Cursor Fix in Web

- v1.0 migration guide: 1-0-migration-checklist.md
- Help and community:
- Where to get help: help-community/help.md
Expand Down
Loading