2.0.0
For the complete documentation index, see llms.txt. For a full content snapshot, see llms-full.txt. Append.mdto anykestra.io/docs/*URL for plain Markdown.
Upgrade from Kestra 1.3 to 2.0.0 by reviewing and applying the breaking changes below.
Start from Kestra 1.3. This guide assumes you are already running the latest 1.3.x release. If you are on an older version, complete the required metadata migrations before upgrading to 2.0.0:
- KV Store and Secrets metadata migration (introduced in 1.1)
- Namespace Files metadata migration (introduced in 1.2)
If you are upgrading directly from 1.0, the LTS migration guide (1.0 → 1.3) consolidates all required steps in one pass.
Before you start
Back up your database
Take a full database backup before upgrading. Several 2.0 migrations are irreversible: in particular, the BasicAuth password rehash prevents rollback to 1.x.
Run database migrations (EE)
Enterprise Edition users must run database migrations manually before starting Kestra 2.0. By default, Kestra EE refuses to start if pending migrations exist. Stop your 1.3 instance, then run the following using the 2.0 binary:
kestra migrate plan # preview what will runkestra migrate run # apply migrationsOpen-source users do not need to do this manually; migrations run automatically on startup.
See Database Migrations for the full upgrade sequence, Docker Compose and Kubernetes examples, and configuration options.
Inventory your flows
Before upgrading, scan your flow sources for constructs that are removed in 2.0:
grep -rl "pluginDefaults:" flows/grep -rl "ForEach\|ForEachItem" flows/grep -rl "conditions:" flows/grep -rl "preconditions:" flows/grep -rl "json(" flows/grep -rl "workerGroup.key" flows/Fix each match using the guides below before restarting Kestra.
Migration tooling
Two tools are available to reduce manual effort during the upgrade.
kestra-migrate CLI
kestra-migrate is a command-line tool that automatically rewrites v1.3 flow YAML to the v2.0 format. It covers 16 migration rules (type renames, property renames, auth restructuring, and more) and flags flows that use removed types requiring manual rewriting.
Install on macOS or Linux:
curl -fsSL https://raw.githubusercontent.com/kestra-io/kestra2-flow-migration/main/install-scripts/install.sh | bashCheck which flows need migration:
kestra-migrate --check ./flows/Migrate flows to an output directory:
kestra-migrate -o v2-flows/ ./flows/Run --check first to scope the work. After kestra-migrate runs, use the guides below for the two patterns the CLI cannot handle automatically: the json() function and pluginDefaults replacement.
Claude Code migration skill
The migrate-kestra-2 Claude Code skill guides the full upgrade journey: pre-flight access audit, server upgrade (Docker Compose and Helm paths), CLI-first flow migration using kestra-migrate, and guided rewrites for patterns the CLI does not cover.
Install:
git clone git@github.com:kestra-io/agent-skills.gitln -s $(pwd)/agent-skills/skills/migrate-kestra-2 ~/.claude/skills/migrate-kestra-2Then open any Claude Code session and say: “migrate my Kestra instance to 2.0”.
What changed in 2.0.0
The changes below are grouped by the area they affect. Work through the categories relevant to your setup; not every change applies to every installation.
Flows
Changes that affect how flows are written or behave at runtime. Review all of these before upgrading, regardless of edition.
| Guide | Editions | What changed |
|---|---|---|
| ForEach replaced by Loop | OSS, EE | ForEach and ForEachItem are removed. Migrate all uses to the Loop task before upgrading; flows that reference either task fail to parse in 2.0. |
| Trigger conditions redesign | OSS, EE | The conditions list and preconditions block on triggers are removed. All trigger types now use a top-level when Pebble expression. |
| condition → when (Checks) | OSS, EE | The condition property on flow-level checks is renamed to when. |
| json() → fromJson() | OSS, EE | The json() Pebble function is removed. Replace all calls with fromJson(); the signature is identical. |
| local.Delete recursive default | OSS, EE | io.kestra.plugin.fs.local.Delete now defaults recursive to false. Flows deleting directories without setting recursive explicitly will stop removing subdirectory contents. |
Two additional removals have no dedicated guide. The four tasks io.kestra.plugin.core.execution.Count, Resume, trigger.Toggle, and log.Fetch are removed from core; replace them with the equivalent tasks from plugin-kestra. The CANCELED execution state alias is also removed; replace with CANCELLED (double-L) in flow expressions, API clients, and any tooling that reads execution state.
Governance and plugins
Changes to flow configuration, permissions, and plugin defaults. The SDK auth and pluginDefaults changes apply to all editions; RBAC is EE only.
| Guide | Editions | What changed |
|---|---|---|
| SDK authentication required for internal tasks | OSS, EE | Tasks that call the Kestra API internally (git sync tasks, and others) now require explicit credentials. Add an auth block to the task, configure a namespace/tenant default service account, or set kestra.tasks.sdk.authentication in your server config. |
| pluginDefaults removed | OSS, EE | The pluginDefaults keyword is removed at all scopes. EE users migrate to Policies; OSS users inline task values manually. |
| pluginDefaults.forced removed from flows | OSS, EE | The forced property on flow-level pluginDefaults is removed. Use Add rules with override: true in a Policy (EE) or inline the values (OSS). |
| RBAC action model | EE | The CRUD-based permission model is replaced by a resource and action model. Existing roles are migrated automatically; CLI role definitions require updates. |
Data and storage
Changes to execution data formats, API responses, and storage configuration.
| Guide | Editions | What changed |
|---|---|---|
| Execution API response | OSS, EE | The execution endpoint response no longer includes task run outputs. Update any API consumers that read taskRunList[*].outputs. |
| ION binary format | OSS, EE | ION task output files are now written in binary format. Expressions that call read() on ION output and then perform string operations will fail; wrap with fromIon(). |
| Execution data in internal storage removed | EE | The configuration option that stored task run outputs in internal storage is removed. Remove the affected keys from your configuration. |
Infrastructure
Changes to deployment, Helm charts, and server configuration. Relevant primarily for operators and platform teams.
| Guide | Editions | What changed |
|---|---|---|
| Database migrations | OSS, EE | How to run the 2.0 schema migrations, including the upgrade sequence, Docker Compose and Kubernetes examples, and key scripts. |
| Helm gRPC worker-controller | EE | Port 50051 is now exposed by default on all pods, and a dedicated controller deployment is added to the Helm chart. The workerGroup.key property is removed; migrate to workerSelector.tags. The fallback default changes from WAIT to FAIL. Review before upgrading. |
| Management endpoint hardening | OSS, EE | Several management endpoints that were open without authentication in 1.x now require explicit opt-in. Review before upgrading in production. |
Terraform provider
Changes to the official Terraform provider. Relevant for teams managing Kestra resources as Infrastructure as Code.
| Guide | Editions | What changed |
|---|---|---|
| Terraform provider | EE, Cloud | The permissions block on kestra_role is renamed to resources with actions instead of CRUD verbs; plugin_defaults and worker_group are removed from kestra_namespace; kestra_template resources must be deleted. Pin to ~> 2.0. |
| Super Admin renamed to Instance Owner | EE, Cloud | The Super Admin privilege is renamed to Instance Owner. Deprecated CLI, config, and request-body aliases are retained. HTTP API responses emit instanceOwner instead of superAdmin; update API consumers that read this field. |
Completing the migration
Migration is complete when the 1.3 instance has no flows remaining. Migrate them one at a time using this sequence:
- Migrate dependencies first. A flow will break at runtime if any of its dependencies are missing on the 2.0 instance. Before migrating a flow, ensure the following are in place:
- Subflows — migrate and validate any subflows the flow calls before migrating the parent. Removing a subflow from 1.3 while a parent flow still runs there will break in-flight executions.
- Namespace files — sync any namespace files the flow reads.
- KV store — migrate KV entries the flow reads at runtime.
- Secrets — confirm secrets are available in the 2.0 secret backend.
- Validate on 2.0. Trigger at least one test execution on the 2.0 instance and confirm it completes successfully.
- Drain before removing. Wait for any active executions of the flow on 1.3 to finish before deleting it. Removing a flow with running executions leaves those executions in an unresolvable state.
- Activate triggers on 2.0 first. If the flow has a schedule or polling trigger, confirm the trigger is active on 2.0 before removing the flow from 1.3; otherwise scheduled runs are silently dropped during the gap.
- Delete from 1.3. Once validated, drained, and triggers are live, delete the flow from the 1.3 instance.
Was this page helpful?