﻿---
title: Migrate workflows from 9.3 to 9.4
description: Port workflows from the 9.3 technical preview to 9.4 GA. Covers the Cases namespace migration, HTTP step configuration changes, and schedule minimum interval.
url: https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/authoring-techniques/migrate-from-9-3
products:
  - Elastic Cloud Enterprise
  - Elastic Cloud Hosted
  - Elastic Cloud Serverless
  - Elastic Cloud on Kubernetes
  - Elastic Stack
  - Kibana
applies_to:
  - Elastic Cloud Serverless: Generally available
  - Elastic Stack: Generally available since 9.4
---

# Migrate workflows from 9.3 to 9.4
9.4 brings a handful of breaking changes to the workflow schema and HTTP step runtime behavior. Existing 9.3 workflows continue to run in most cases: the deprecated step aliases still resolve, `timeout` auto-migrates on save, and sub-minute schedules auto-migrate when edited. However, deployments with restrictive outbound action connector hosts might need a Kibana configuration update for HTTP steps.
This guide is the side-by-side for the migrations every 9.3 workflow author needs.

## Summary


| Change                             | Old (9.3)                                                                                                                           | New (9.4)                                                                                                           | What happens to existing workflows                                                                                                                                   |
|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Case management                    | `kibana.createCaseDefaultSpace`, `kibana.getCaseDefaultSpace`, `kibana.updateCaseDefaultSpace`, `kibana.addCaseCommentDefaultSpace` | `cases.createCase`, `cases.getCase`, `cases.updateCase`, `cases.addComment` (plus 23 additional `cases.*` steps)    | Deprecated aliases still work. New workflows must use `cases.*`.                                                                                                     |
| HTTP step `timeout`                | Inside `with`                                                                                                                       | At the step top level (common field)                                                                                | Existing workflows auto-migrate on save.                                                                                                                             |
| HTTP step allowed hosts            | `workflowsExecutionEngine.http.allowedHosts` controlled workflow HTTP steps. The default was `["*"]`.                               | `xpack.actions.allowedHosts` controls HTTP steps because they now run through the Actions framework HTTP connector. | If `xpack.actions.allowedHosts` is unset, the default is still `["*"]`. If it is set restrictively, existing HTTP steps can fail until their target hosts are added. |
| Scheduled trigger interval minimum | Any duration                                                                                                                        | Minimum `1m` / `60s`                                                                                                | Sub-minute intervals auto-migrate to `1m` on first edit.                                                                                                             |


## 1. Cases: `kibana.*` aliases to `cases.*`

Case management moved out of the `kibana.*` namespace into its own `cases.*` namespace, and the new namespace uses `snake_case` parameters instead of the old `camelCase`.
9.4 also adds many new case steps that have no 9.3 equivalent. Check [Cases action steps](https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/steps/cases) for the complete catalog.

### Create a case

```yaml
# Old (9.3 — deprecated alias still works)
- name: open_case
  type: kibana.createCaseDefaultSpace
  with:
    title: "Alert on host-1"
    description: "..."
    severity: "high"
```

```yaml
# New (9.4)
- name: open_case
  type: cases.createCase
  with:
    title: "Alert on host-1"
    description: "..."
    severity: "high"
    owner: "securitySolution"
```


### Fetch a case

```yaml
# Old
- type: kibana.getCaseDefaultSpace
  with:
    caseId: "abc-123"
```

```yaml
# New
- type: cases.getCase
  with:
    case_id: "abc-123"
```

Note the parameter rename: `caseId` (camelCase) becomes `case_id` (snake_case). This pattern applies to every parameter in the `cases.*` namespace.

### Update a case

The new `cases.updateCase` wraps the field changes in a required `updates` object:
```yaml
# Old
- type: kibana.updateCaseDefaultSpace
  with:
    caseId: "abc-123"
    status: "closed"
    severity: "low"
```

```yaml
# New — fields go inside `updates`
- type: cases.updateCase
  with:
    case_id: "abc-123"
    updates:
      status: "closed"
      severity: "low"
```

For single-field changes, use the dedicated setters:
```yaml
- type: cases.setStatus
  with:
    case_id: "abc-123"
    status: "closed"
```


### Add a comment

```yaml
# Old
- type: kibana.addCaseCommentDefaultSpace
  with:
    caseId: "abc-123"
    comment: "Analyst note"
```

```yaml
# New
- type: cases.addComment
  with:
    case_id: "abc-123"
    comment: "Analyst note"
```


## 2. HTTP step `timeout` relocation

In 9.3, the `http` step accepted `timeout` inside `with`. In 9.4, `timeout` is a standard common step field at the step top level, alongside `if`, `foreach`, `on-failure`, and others.
```yaml
# Old
- type: http
  with:
    url: "https://example.com/webhook"
    timeout: "30s"
```

```yaml
# New
- type: http
  timeout: "30s"
  with:
    url: "https://example.com/webhook"
```

Existing workflows auto-migrate on save. New workflows must use the new shape.

## 3. HTTP step allowed hosts

In 9.3, `type: http` steps without a `connector-id` used the workflow execution engine HTTP client and were controlled by `workflowsExecutionEngine.http.allowedHosts`.
In 9.4, those HTTP steps run through the Actions framework HTTP connector. As a result, outbound URLs are validated against [`xpack.actions.allowedHosts`](https://www.elastic.co/docs/reference/kibana/configuration-reference/alerting-settings#action-settings).
If `xpack.actions.allowedHosts` is not set, it defaults to `["*"]`, so all hosts are allowed. If your deployment sets a restrictive allowlist, add the hosts used by workflow HTTP steps:
```yaml
xpack.actions.allowedHosts: ["api.example.com", "hooks.example.net"]
```

To allow all outbound hosts:
```yaml
xpack.actions.allowedHosts: ["*"]
```

This setting applies to all action connectors, including connectors used by workflows. It does not apply to integrations, and it cannot currently be scoped per connector or per workflow.
For self-managed deployments, configure this in `kibana.yml` and restart Kibana. On Elastic Cloud Hosted, configure it in the deployment's Kibana user settings.
<note>
  If an upgraded workflow HTTP step fails with an `unexpected error`, check whether the target host is blocked by `xpack.actions.allowedHosts`.
</note>


## 4. Scheduled trigger minimum interval

9.3 accepted any `with.every` value on a scheduled trigger, including sub-minute intervals such as `30s`. 9.4 enforces a minimum of `1m` / `60s`.
```yaml
# Old (9.3 — accepted)
triggers:
  - type: scheduled
    with:
      every: "30s"
```

```yaml
# New (9.4 — rejected at save time)
triggers:
  - type: scheduled
    with:
      every: "1m"  
```

Existing 9.3 workflows with sub-minute intervals auto-migrate to `1m` when first edited.
<tip>
  If `every: "30s"` was a proxy for reacting quickly to something, consider switching to an [alert trigger](https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/triggers/alert-triggers) or an [event-driven trigger](https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/triggers/event-driven-triggers). Scheduled polling is the slowest of the three trigger types.
</tip>


## What else is new in 9.4

Beyond the breaking changes, 9.4 adds many capabilities that don't require you to change existing workflows but are available for new ones:
- **Workflows is enabled by default.** The `workflows:ui:enabled` advanced setting now defaults to `true` on deployments with the appropriate [subscription](https://www.elastic.co/pricing) in Elastic Stack or [project feature tier](https://www.elastic.co/elastic/docs-builder/docs/3371/deploy-manage/deploy/elastic-cloud/project-settings) in Serverless.
- **27 `cases.*` steps.** Full Cases API coverage. To learn more, refer to [Cases action steps](https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/steps/cases).
- **Composition (technical preview).** Call child workflows with typed inputs and outputs. To learn more, refer to [Composition steps](https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/steps/composition).
- **Human-in-the-loop.** Pause a workflow and resume after a human provides input. To learn more, refer to [Human-in-the-loop](https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/authoring-techniques/human-in-the-loop).
- **Event-driven triggers (technical preview).** React to other workflow failures. To learn more, refer to [Event-driven triggers](https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/triggers/event-driven-triggers).
- **`while` and `switch` flow control.** Even more control over workflow logic. To learn more, refer to [Flow control steps](https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/steps/flow-control-steps).
- **Expanded AI steps.** `ai.classify` and `ai.summarize` join `ai.prompt` and `ai.agent`. To learn more, refer to [AI steps](https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/steps/ai-steps).
- **Data transformation steps.** 11 `data.*` steps for inline data work: filter, map, aggregate, parse JSON, regex extract, and more. To learn more, refer to [Data action steps](https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/steps/data).


## Related

- [Cases action steps](https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/steps/cases): Complete `cases.*` reference.
- [Flow control steps](https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/steps/flow-control-steps): `while`, `switch`, and the other flow-control types added in 9.4.
- [Scheduled triggers](https://www.elastic.co/elastic/docs-builder/docs/3371/explore-analyze/workflows/triggers/scheduled-triggers): Trigger configuration reference.