For the complete documentation index, see llms.txt.
Skip to main content
Version: 8.11 (unreleased)

Upgrade Camunda 8.9 to 8.10 using Helm

Upgrade a Helm-managed Camunda 8 Self-Managed deployment from version 8.9 to 8.10.

Upgrade procedure

All Camunda 8 upgrades must follow the required upgrade procedure. First, upgrade to the latest patch of your current minor. Then, upgrade one minor version at a time. Don't skip minor versions.

If you skip a minor version, the schema compatibility check fails and blocks startup. We strongly recommend that you upgrade to the latest patch of each minor for fix coverage. However, the check itself compares minor versions.

See version compatibility checks.

Prerequisites​

Before you upgrade, make sure you meet these prerequisites:

PrerequisiteDescription
Confirm 8.9.x baselineCheck that your deployment runs an 8.9.x version before you upgrade to 8.10. If you upgrade from a version earlier than 8.9, upgrade one minor at a time. See upgrading from an earlier version. We strongly recommend that you upgrade to the latest available 8.9.x patch first, for fix coverage.
Confirm Helm CLI versionCamunda 8.10 (chart 15.x) supports Helm CLI v3 (3.10 or later) and v4. See Helm CLI support and chart compatibility and Move from the Helm v3 CLI to v4.
Confirm upgrade eligibilityReview Prepare for upgrade to check upgrade eligibility and to check infrastructure compatibility for 8.10.
Confirm Helm chart supportReview the Camunda Helm chart version matrix to find the chart version that deploys 8.10. The matrix also shows the Helm CLI versions that this chart version was released and tested with. Check your Kubernetes version against the supported environments.
Migrate bundled Bitnami subchartsIf your 8.9 release uses identityKeycloak, identityPostgresql, webModelerPostgresql, or elasticsearch, migrate to externally managed services. Do this while you still run 8.9, before you upgrade. Chart 15.x no longer deploys these subcharts. See Migrate from Bitnami charts.
BackupsCreate backups of your Camunda data. Check the backups. Backup and restore covers Zeebe, Operate, Tasklist, Admin, and Optimize. To create a backup of the Web Modeler database, follow Hub database backup. Create backups of the Management Identity and Keycloak databases with your database vendor's tooling. The Backup and restore guide doesn't cover these databases.
Check your values.yamlReview your existing values.yaml for keys that chart 15.x rejects, deprecated Helm keys, and changed chart defaults.
Plan the Camunda Hub migrationIf your release runs Web Modeler, plan a maintenance window. The Hub database migration isn't backward compatible. The migration requires you to stop all Web Modeler workloads. The upgrade also removes the Console Deployment, because Hub replaces Console. See Migrate Web Modeler and Console to Hub.
Test upgradeTest the upgrade in a non-production environment. Use a copy of your production configuration.

Upgrade flow​

After completing the prerequisites, follow this flow for each supported minor-version upgrade:

  1. Run the Camunda Helm Toolkit to migrate and validate override files.
  2. Review the report and complete the version-specific manual actions.
  3. Render and test the complete, layered configuration in non-production.
  4. Back up data and run the Helm upgrade.
  5. Validate the deployed platform.

Run the Camunda Helm Toolkit​

Start values-file preparation by running the toolkit against your Helm override files. Review and address its findings before completing the manual upgrade steps below.

  1. Keep a copy of your original 8.9 overrides. Run the toolkit with source 8.9 and target 8.10 to create values-8.10.yaml. For layered overrides, migrate each file separately and retain the Helm -f order.
  2. Inspect the migrated YAML and act on the report. Resolve errors before using the output and review warnings for manual actions.
  3. Review the manual configuration changes, including changed chart defaults, and complete all actions that apply to your deployment, including actions not identified by the report.

A clean report is a useful sanity check, not proof of production readiness. Complete the applicable manual actions even when the report has no findings. The toolkit prepares override files; it doesn't upgrade your deployment, migrate stored data, or validate a live cluster. Follow the complete upgrade procedure, including the Hub database migration if you run Web Modeler.

Update your values file to 8.10​

Apply the manual configuration changes that your deployment needs. Use the report to locate relevant settings, and review these sections for changes the toolkit doesn't automate.

Consolidate Console and Web Modeler into Camunda Hub​

Camunda 8.10 consolidates Console and Web Modeler into Camunda Hub. Console is no longer a standalone deployment. The camunda/hub image serves both feature sets.

Enable Hub​

Replace the legacy enablement keys with camundaHub.enabled. Move overrides directly under camundaHub:

# Before (8.9)
console:
enabled: true
webModeler:
enabled: true
restapi:
resources:
requests:
memory: 1Gi

# After (8.10)
camundaHub:
enabled: true
restapi:
resources:
requests:
memory: 1Gi

The legacy webModeler.enabled key remains a compatibility shim in 8.10. It deploys Hub and emits a deprecation warning. Existing webModeler.* settings remain fallback values. However, migrate them to the equivalent flattened camundaHub.* paths.

Don't nest settings under camundaHub.webModeler or camundaHub.console. If you nest settings under either key, the chart fails the render.

The setting camundaHub.enabled: true also enables the Console feature. If your 8.9 release ran only Web Modeler, Hub shows Console's cluster pages after the upgrade.

Merge webModeler and camundaHub values​

The chart deep-merges camundaHub.* over webModeler.*, and a value under camundaHub wins:

  • Maps merge key by key, so a map under camundaHub can't remove a key that webModeler sets.
  • Lists don't merge. A list under camundaHub, such as camundaHub.restapi.env, extraVolumes, extraConfiguration, tolerations, or initContainers, replaces the whole list under webModeler. When you move a list, move all of its entries.
  • If you set a scalar under camundaHub where webModeler has a map, or the reverse, the chart fails the render.

Deploy Camunda Hub for a Console-only release​

console.enabled: true doesn't deploy anything on its own in 8.10. Hub runs only when camundaHub.enabled or webModeler.enabled is true. console.enabled has an effect only when Hub runs through the legacy webModeler.enabled. Then it enables the Console feature inside Hub. With camundaHub.enabled: true, the Console feature is always enabled, and console.enabled: false doesn't disable it.

If your 8.9 release ran Console without Web Modeler, do these steps. Set camundaHub.enabled: true. Keep Management Identity configured as it was for Console. Add the settings Hub needs:

SettingHelm key
External PostgreSQL databasecamundaHub.restapi.externalDatabase.*. The chart doesn't check this setting at render time.
Sender address for Hub emailscamunda.hub.mail.from-address in camundaHub.restapi.extraConfiguration. The render fails without this setting.
SMTP server for Hub emailsspring.mail.* in camundaHub.restapi.extraConfiguration. Hub sends no emails without this setting.
Public URL for the login callbackglobal.identity.auth.camundaHub.redirectUrl. It replaces global.identity.auth.console.redirectUrl.
Path Hub is served oncamundaHub.contextPath. Set this key when the chart renders your Ingress or Gateway API routes. Without this key, the shared Ingress has no Hub path, and the Kubernetes API server rejects the Hub HTTPRoute.

If you use an external OIDC provider, Hub authenticates with the client ID web-modeler and the audiences web-modeler-api and web-modeler-public-api. Hub uses these values unless you set global.identity.auth.camundaHub.clientId, clientApiAudience, and publicApiAudience. Register Hub's applications in your provider. The Console application doesn't cover them. See connect to an OIDC provider.

A Console-only release has no 8.9 Hub database, so the release doesn't need the database migration phases. Run the one-step upgrade in Run the Helm upgrade.

Move or remove console keys​

The chart reads only console.enabled. It ignores every other console.* key. It emits a single deprecation warning when you set any of them. Move the settings that you still need to Hub. Then remove the console block:

8.9 key8.10 key or action
console.resourcescamundaHub.restapi.resources. See Review Hub REST API resources.
console.env, console.envFromcamundaHub.restapi.env, camundaHub.restapi.envFrom. Don't move CAMUNDA_CONSOLE_* variables or camunda.console properties. Hub fails on startup if you set them. See Console configuration.
console.replicas, console.nodeSelector, console.tolerations, console.affinity, console.podLabels, console.podAnnotations, console.extraVolumes, console.extraVolumeMounts, console.initContainers, console.sidecars, console.podSecurityContext, console.containerSecurityContext, console.dnsPolicy, console.dnsConfigUse the same keys under camundaHub.restapi. Lists replace the webModeler.restapi lists. See Merge webModeler and camundaHub values.
console.serviceAccount.*camundaHub.serviceAccount.*. The Hub REST API and WebSockets pods share this service account.
console.contextPathNo equivalent. Hub serves Console's pages on camundaHub.contextPath.
console.configuration, console.extraConfiguration, console.overrideConfigurationCluster configuration moves to camundaHub.restapi.clusters. If you set this key, your value replaces the cluster list the chart generates for the release. As a result, list the release's own clusters too. See cluster configuration.
console.image.registry, console.image.pullSecretscamundaHub.image.registry, camundaHub.image.pullSecrets.
console.image.repository, console.image.tag, console.image.digestNo equivalent. Remove these keys. To pin Hub images, see Update image references.
console.tls.*If Console needed these keys to trust a private CA, add that CA to the PEM bundle in global.tls.caBundle.secret. Otherwise, remove them.
console.keycloak.realmNo equivalent. Remove this key.

global.identity.auth.console.* has no effect in 8.10, and the chart emits a deprecation warning when you set it. For a Console-only release, set global.identity.auth.camundaHub.redirectUrl to Hub's public URL. This key replaces global.identity.auth.console.redirectUrl. The other keys have no direct replacement, so remove them.

Management Identity doesn't remove the existing console client from Keycloak. See Management Identity roles and permissions.

Update references to Console​

The chart no longer renders the Console Deployment, Service, ServiceMonitor, and HTTPRoute, or the /console path on the shared Ingress. Helm removes them during the upgrade. Update bookmarks, external Ingress or Gateway routes, and monitoring that target Console to use Hub instead. If the chart renders your Ingress or Gateway API routes, set camundaHub.contextPath. Without it, the shared Ingress has no Hub path, and the Kubernetes API server rejects the Hub HTTPRoute.

Update image references​

If you mirror or pin images, update these repositories:

8.9 image8.10 image
camunda/web-modeler-restapi:8.9.xcamunda/hub:8.10.x
camunda/web-modeler-websockets:8.9.xcamunda/hub-websockets:8.10.x
camunda/console:8.9.xThe chart no longer deploys this image. Console runs in camunda/hub.

Configure the Hub repositories under camundaHub.restapi.image.repository and camundaHub.websockets.image.repository.

Image pins under webModeler stay in effect through the fallback. For example, webModeler.image.tag: 8.9.10 renders camunda/hub:8.9.10, which doesn't exist. A pinned webModeler.restapi.image.repository or webModeler.websockets.image.repository keeps the 8.9 image. Remove the 8.9 image pins from webModeler. Pin both Hub images with camundaHub.image.tag.

Review Hub REST API resources​

Console now runs in the Hub REST API pod. However, the Hub REST API keeps the resource defaults of the 8.9 Web Modeler REST API:

PodRequests (CPU / memory)Limits (CPU / memory)
8.9 Console1000m / 1Gi2000m / 2Gi
8.9 Web Modeler REST API900m / 1280Mi1800m / 2560Mi
8.10 Hub REST API900m / 1280Mi1800m / 2560Mi

If you ran Console, set camundaHub.restapi.resources explicitly. In that case, adjust the requests and limits if the pod is throttled or exhausts its memory.

Remove keys rejected by chart 15.x​

Chart 15.x rejects removed values before it changes any workloads. Update or remove these values before you upgrade:

Removed keys
Removed keyReplacement or action
global.ingress.hostUse global.host.
global.identity.keycloak.auth.existingSecretUse global.identity.keycloak.auth.secret.existingSecret. Also set global.identity.keycloak.auth.secret.existingSecretKey. In chart 14.x, the default value of the key was admin-password. Chart 15.x has no default. Without the key, Management Identity receives an empty Keycloak admin password.
global.identity.keycloak.auth.existingSecretKeyUse global.identity.keycloak.auth.secret.existingSecretKey.
global.elasticsearch.*Use optimize.database.elasticsearch.* for Optimize. Use orchestration.data.secondaryStorage.elasticsearch.* for the Orchestration Cluster. See the migration mapping below.
global.opensearch.*Use optimize.database.opensearch.* for Optimize. Use orchestration.data.secondaryStorage.opensearch.* for the Orchestration Cluster. See the migration mapping below.
orchestration.profiles.identityUse orchestration.profiles.admin.
webModeler.restapi.externalDatabase.userUse camundaHub.restapi.externalDatabase.username.
identityKeycloak, identityPostgresqlMigrate Keycloak and the Management Identity database to externally managed services while you're still on 8.9. Chart 15.x doesn't render the bundled workloads, so Helm removes their StatefulSets during the upgrade. See migrate off the bundled PostgreSQL databases.
webModelerPostgresqlMigrate the Camunda Hub database to external PostgreSQL while you're still on 8.9. Also configure camundaHub.restapi.externalDatabase. See migrate off the bundled PostgreSQL databases.
elasticsearchMigrate to external Elasticsearch or OpenSearch while you're still on 8.9. Also configure the secondary storage values of each component.

The chart rejects these keys whenever they're in your values file, even when their block only sets enabled: false, such as elasticsearch: {enabled: false}.

Two checks apply only to a deployed component. The check for orchestration.profiles.identity applies when the chart deploys the Orchestration Cluster. The check for webModeler.restapi.externalDatabase.user applies when the chart deploys Hub. Remove the whole block from your values file.

Migrate global.elasticsearch and global.opensearch​

Chart 14.x deprecated the global.elasticsearch.* and global.opensearch.* trees, and chart 15.x removes them. If you set any key under them, the render fails with [camunda][error] The Helm values file key "global.elasticsearch" has been removed. A message that names the replacement keys follows.

The table shows the Elasticsearch keys. The OpenSearch keys mirror the Elasticsearch keys, except external and disableExporter, which exist only for Elasticsearch. Map your values as follows:

Removed keys
Removed keyReplacement
global.elasticsearch.enabledUse optimize.database.elasticsearch.enabled (Optimize and the legacy Zeebe exporter), orchestration.data.secondaryStorage.type: elasticsearch, or both. If you enable Optimize, set optimize.database.elasticsearch.enabled: true. The secondary storage type alone doesn't configure the Optimize database or the exporter that writes the indices that Optimize reads. The chart renders the legacy Zeebe exporter when you enable Optimize with optimize.database.elasticsearch.enabled: true and the cluster doesn't span more than one region or zone. The chart also renders the exporter when you set orchestration.exporters.zeebe.enabled: true with Elasticsearch secondary storage.
global.elasticsearch.externaloptimize.database.elasticsearch.external.
global.elasticsearch.url.*Use optimize.database.elasticsearch.url.{protocol,host,port}, the full-URL string orchestration.data.secondaryStorage.elasticsearch.url, or both. When orchestration.data.secondaryStorage.elasticsearch.url is empty, the Orchestration Cluster uses the Optimize URL. Set the URL explicitly. The Optimize default, http://<RELEASE>-elasticsearch:9200, is the address of the bundled subchart that chart 15.x no longer deploys.
global.elasticsearch.auth.*Set both optimize.database.elasticsearch.auth.* and orchestration.data.secondaryStorage.elasticsearch.auth.*. The secondary storage of the Orchestration Cluster doesn't reuse the Optimize credentials, even when the Orchestration Cluster reuses the Optimize URL. When Optimize owns the legacy Zeebe exporter, the exporter authenticates with optimize.database.elasticsearch.auth.*. The exporter does this only when optimize.database.elasticsearch.external is true.
global.elasticsearch.tls.secret.*, global.elasticsearch.tls.existingSecretUse global.tls.caBundle.secret with a PEM CA bundle. The per-component optimize.database.elasticsearch.tls.secret.* and orchestration.data.secondaryStorage.elasticsearch.tls.secret.* keys still work, but chart 15.x deprecates them. See move per-component truststores to global.tls.caBundle.
global.elasticsearch.tls.jks.secret.*Chart 15.x removes this key together with the truststore password injection. Use global.tls.caBundle.secret (PEM). Alternatively, pass -Djavax.net.ssl.trustStorePassword=... in the javaOpts of the component. To keep the password in a Secret, load the Secret with the envFrom of the component. Then reference the key of the Secret as $(KEY) in javaOpts. The chart renders JAVA_TOOL_OPTIONS before the component's env entries, so a $(VAR) reference to a variable defined in env doesn't expand. A reference to a variable that envFrom loads does expand.
global.elasticsearch.prefixUse optimize.database.elasticsearch.prefix. Chart 15.x also deprecates this key. See Optimize. The legacy Zeebe exporter writes its indices with orchestration.exporters.zeebe.index.prefix. If this key is unset, the exporter uses optimize.database.elasticsearch.prefix. If that key is also unset, the exporter uses zeebe-record.
global.elasticsearch.clusterNameThe chart no longer renders this key. The application default is identical. If you need this setting, set camunda.data.secondary-storage.elasticsearch.cluster-name in orchestration.extraConfiguration.
global.elasticsearch.disableExporterYou don't need a replacement. The key had no effect.
global.elasticsearch.tls.enabledYou don't need a replacement. The key had no effect. The connection uses TLS when the URL scheme is https. tls.secret.* and global.tls.caBundle only supply the CA that the component trusts.
global.opensearch.aws.enabledThe key applies only to OpenSearch and has no Elasticsearch equivalent. Use optimize.database.opensearch.aws.enabled, orchestration.data.secondaryStorage.opensearch.aws.enabled, or both.

Migrate off the bundled PostgreSQL databases​

Chart 15.x removes the bundled Bitnami PostgreSQL subcharts. The chart fails the render if your values file still contains identityPostgresql or webModelerPostgresql. Do this migration on your 8.9 release, before you upgrade to 8.10.

For each database that Management Identity or Camunda Hub uses in a bundled PostgreSQL:

  1. Migrate the data to a database that the chart doesn't manage. This can be your own deployment of Bitnami PostgreSQL, a managed cloud database, or a different supported PostgreSQL. See migrate from Bitnami charts.
  2. Point the 8.9 release at the external database. Verify that Management Identity or Web Modeler works with it.
  3. Before you remove the bundled database, protect its volume. Do these steps:
    1. Examine the reclaim policy of its PersistentVolume and the persistentVolumeClaimRetentionPolicy of its StatefulSet.
    2. Set persistentVolumeReclaimPolicy of the PersistentVolume to Retain.
    3. Make a backup and verify that you can restore it.
  4. Remove the bundled database.
warning

If the volume is deleted with the StatefulSet or its PVC, you lose its data. For Management Identity, this is users, groups, roles, and permissions. For Web Modeler, this is projects, files, and settings.

Management Identity service account token is no longer mounted by default​

In chart 15.x (8.10), identity.serviceAccount.automountServiceAccountToken defaults to false, like in the other components. Management Identity doesn't call the Kubernetes API, so this change doesn't affect the application itself.

The change affects you if anything in the Management Identity pod reads the default service account token at /var/run/secrets/kubernetes.io/serviceaccount/token. For example:

  • A sidecar or init container that you add through identity.sidecars or identity.initContainers and that calls the Kubernetes API.
  • Vault Agent Injector with the Kubernetes auth method and the default token.

The change doesn't affect integrations that inject their own projected token, such as AWS IRSA, EKS Pod Identity, and Azure Workload Identity.

helm upgrade updates the ServiceAccount. However, running pods keep their token until Kubernetes creates them again. The change takes effect on the next pod restart or rollout. To keep the previous behavior, set:

identity:
serviceAccount:
automountServiceAccountToken: true

Camunda Hub Recreate strategy requires existingClaim​

In chart 15.x (8.10), deploymentStrategy: Recreate requires persistence.enabled: true and persistence.existingClaim. If one of these settings is missing, the render fails with a [camunda][error] message. The requirement applies to webModeler.persistence and camundaHub.persistence. The default RollingUpdate strategy is not affected.

The 8.9 chart renders Recreate with persistence.enabled: true and no existingClaim. It emits a [camunda][warning] instead of an error.

Before you upgrade, do one of the following:

  • Set persistence.existingClaim with persistence.enabled: true.
  • Remove deploymentStrategy: Recreate.

Deprecated application configuration Helm keys​

Chart 15.x (8.10) deprecates Helm keys that acted as thin proxies for a single application setting, in favor of the component's extraConfiguration. These keys continue to work in 8.10, except the keys that the tables say have no effect.

If you set one of these keys to a non-default value, the chart prints a [camunda][warning] DEPRECATION message in the helm install or helm upgrade output. If global.createReleaseInfo is false, the chart doesn't print the message in that output. The message also appears in the <RELEASE-FULLNAME>-warnings ConfigMap.

The message says that chart v16 (Camunda 8.11) removes the key. If you migrate the keys while you're on 8.10, your values file stays ready for that removal.

Deprecations are still being added

Camunda 8.10 is under active development. Camunda may deprecate more keys during the 8.10 release cycle. The tables below cover the keys that Camunda deprecated at the time of writing. Treat the [camunda][warning] DEPRECATION messages that your own helm upgrade emits as the authoritative, up-to-date list for your chart version. Each message names the deprecated key and where to configure it instead.

With extraConfiguration, each component can own the native configuration file of its application. The format is the same as in 8.9. It's an ordered list of file entries. For Spring Boot components, the chart mounts the files and imports them through spring.config.import.

To learn how extraConfiguration works in each component, see Application configuration and extraConfiguration. The same page explains how to exclude non-Spring files with springImport: false.

To find the property that the chart generates for a key, render the configuration of the component. For example, render it with helm template <RELEASE> camunda/camunda-platform --version <CHART_VERSION> -f values-8.10.yaml --show-only templates/orchestration/configmap.yaml. Then find the equivalent property in the rendered configuration.

For the deprecated keys below, the value in your extraConfiguration overrides the value that the chart renders. This happens because Spring Boot applies imported files after the chart's application.yaml. You don't need to remove the deprecated key at the same time. When you migrate, note these points:

  • For orchestration.exporters.camunda.enabled, the document store, and the keys of Optimize and Camunda Hub, the chart also reads your extraConfiguration itself. For most of these keys, the chart recognizes only nested YAML keys in the first document of a file that Spring imports. The chart doesn't recognize flat dotted keys such as camunda.data.snapshot-period. Therefore, write migrated properties as nested YAML.
  • The chart doesn't process extraConfiguration content as a template. Write final values instead of expressions such as {{ .Release.Name }}.
  • If you set orchestration.configuration, this setting replaces the generated application.yaml, including its spring.config.import list. As a result, the chart doesn't import your extraConfiguration files, unless your file imports them.
  • Some chart defaults differ from the application defaults. For example, orchestration.cpuThreadCount and orchestration.ioThreadCount have the chart default 3 and the application default 2. The key orchestration.history.rolloverBatchSize has the chart default 100 and the application default 500. The chart still renders its defaults in 8.10. To keep a chart default after the chart removes the key, set that value explicitly when you migrate.

Move each deprecated key to the extraConfiguration of the listed component, except where the notes say otherwise.

Orchestration​

Move these keys to orchestration.extraConfiguration. If the notes say that a key has no effect, remove the key instead.

From orchestration.history.retention.enabled, the chart also renders camunda.operate.archiver.ilmEnabled and camunda.tasklist.archiver.ilmEnabled. The 8.10 application doesn't read these properties, so you don't need to migrate them.

Deprecated orchestration keys
KeyNotes
orchestration.logLevelUse logging.level.io.camunda.zeebe. To set the level for all Camunda loggers, use logging.level.io.camunda. Alternatively, use a log4j2.xml entry. The chart rendered this key as zeebe.log.level. The application doesn't read zeebe.log.level, so the key had no effect in 8.9 either.
orchestration.log4j2Move the key to a file-content extraConfiguration entry (log4j2.xml) with springImport: false. See excluding files from spring.config.import.
orchestration.cpuThreadCountcamunda.system.cpu-thread-count
orchestration.ioThreadCountcamunda.system.io-thread-count
orchestration.data.snapshotPeriodcamunda.data.snapshot-period.
orchestration.data.disk.freeSpace.processingcamunda.data.primary-storage.disk.free-space.processing
orchestration.data.disk.freeSpace.replicationcamunda.data.primary-storage.disk.free-space.replication
orchestration.index.prefixcamunda.data.secondary-storage.<elasticsearch|opensearch>.index-prefix. This prefix doesn't apply to the indices of the legacy Zeebe exporter. These indices use orchestration.exporters.zeebe.index.prefix.
orchestration.index.replicascamunda.data.secondary-storage.<elasticsearch|opensearch>.number-of-replicas. When orchestration.exporters.zeebe.replicas is unset, the index.numberOfReplicas of the legacy Zeebe exporter also uses orchestration.index.replicas. Set orchestration.exporters.zeebe.replicas to keep the value of index.numberOfReplicas.
orchestration.history.retention.enabledcamunda.data.secondary-storage.retention.enabled. The chart renders camunda.data.secondary-storage.<elasticsearch|opensearch>.history.policy-name: camunda-history-retention-policy only while orchestration.history.retention.enabled is true. When you migrate the key, also set policy-name. Otherwise, the policy name changes to the application default, camunda-retention-policy.
orchestration.history.retention.minimumAgecamunda.data.secondary-storage.retention.minimum-age
orchestration.history.retention.policyNamecamunda.data.secondary-storage.<elasticsearch|opensearch>.history.policy-name
orchestration.history.delayBetweenRunscamunda.data.secondary-storage.<elasticsearch|opensearch>.history.delay-between-runs
orchestration.history.maxDelayBetweenRunscamunda.data.secondary-storage.<elasticsearch|opensearch>.history.max-delay-between-runs
orchestration.history.rolloverBatchSizecamunda.data.secondary-storage.<elasticsearch|opensearch>.history.rollover-batch-size
orchestration.history.rolloverIntervalcamunda.data.secondary-storage.<elasticsearch|opensearch>.history.rollover-interval
orchestration.history.waitPeriodBeforeArchivingcamunda.data.secondary-storage.<elasticsearch|opensearch>.history.wait-period-before-archiving
orchestration.history.elsRolloverDateFormatcamunda.data.secondary-storage.<elasticsearch|opensearch>.history.els-rollover-date-format
orchestration.retention.enabledzeebe.broker.exporters.<elasticsearch|opensearch>.args.retention.enabled (Zeebe record index). This row and the next two rows apply only when the chart renders the legacy Zeebe exporter.
orchestration.retention.minimumAgezeebe.broker.exporters.<elasticsearch|opensearch>.args.retention.minimumAge (Zeebe record index)
orchestration.retention.policyNamezeebe.broker.exporters.<elasticsearch|opensearch>.args.retention.policyName (Zeebe record index)
orchestration.security.authentication.unprotectedApicamunda.security.authentication.unprotected-api. The value can't be true together with multi-tenancy checks. See Troubleshooting.
orchestration.security.authentication.oidc.usernameClaimcamunda.security.authentication.oidc.username-claim. The chart also uses the Helm key for the Hub REST API (camunda.hub.oauth2.token.username-claim). Keep the Helm key. Alternatively, also set that property in camundaHub.restapi.extraConfiguration.
orchestration.security.authentication.oidc.clientIdClaimcamunda.security.authentication.oidc.client-id-claim
orchestration.security.authentication.oidc.groupsClaimcamunda.security.authentication.oidc.groups-claim
orchestration.security.authentication.oidc.preferUsernameClaimcamunda.security.authentication.oidc.prefer-username-claim
orchestration.security.authentication.oidc.scopecamunda.security.authentication.oidc.scope
orchestration.security.authentication.oidc.backwardsCompatibleAudiencescamunda.security.authentication.oidc.audiences. This property replaces the audience list. See Troubleshooting.
orchestration.security.authentication.authenticationRefreshIntervalcamunda.security.authentication.authentication-refresh-interval. The chart renders the Helm key under camunda.security.authentication.oidc. The application doesn't read the key there, so the key has no effect. Remove the key. If you need a non-default value, set the interval under camunda.security.authentication.
orchestration.security.authorizations.enabledcamunda.security.authorizations.enabled. The chart also writes this value into the Hub cluster configuration. Therefore, keep the Helm key in 8.10.
orchestration.security.initialization.mappingRulescamunda.security.initialization.mapping-rules.
orchestration.security.initialization.defaultRoles.<role>.mappingRulescamunda.security.initialization.default-roles.<role>.mapping-rules. Applies to admin, connectors, and custom roles. This key assigns mapping rule IDs to a role. It does not define the mapping rules. Move the role assignment together with the rule definitions, or users that log in through these mapping rules lose the role.
orchestration.security.initialization.authorizationscamunda.security.initialization.authorizations. The permission list field is permissions, not permissionTypes. See Troubleshooting.
orchestration.multitenancy.checks.enabledcamunda.security.multi-tenancy.checks-enabled
orchestration.multitenancy.api.enabledcamunda.security.multi-tenancy.api-enabled. When global.multitenancy.enabled is true, the chart ignores a false value for the Helm key. Therefore, if you move false to camunda.security.multi-tenancy.api-enabled, this change disables the tenant API.
orchestration.exporters.camunda.enabledcamunda.data.secondary-storage.autoconfigure-camunda-exporter.
orchestration.exporters.zeebe.replicaszeebe.broker.exporters.<elasticsearch|opensearch>.args.index.numberOfReplicas.
orchestration.security.authentication.oidc.redirectUrlThis key is the base redirect URL. The chart derives camunda.security.authentication.oidc.redirect-uri (<base>/sso-callback) from it. The chart also renders camunda.operate.identity.redirectRootUrl and camunda.tasklist.identity.redirectRootUrl, which the 8.10 application doesn't read. Set camunda.security.authentication.oidc.redirect-uri in orchestration.extraConfiguration. If Management Identity registers the Orchestration client, keep this key too. The chart also uses this key as the root-url of that client.
orchestration.upgrade.allowPreReleaseImagescamunda.system.upgrade.enable-version-check. The new property has the opposite meaning. allowPreReleaseImages: true becomes enable-version-check: false.
orchestration.history.retention.usageMetricsMinimumAgeThe chart doesn't render this key in chart 14.x or 15.x, so the key has no effect. Remove the key. To configure the retention, set camunda.data.secondary-storage.retention.usage-metrics-minimum-age.
orchestration.history.retention.usageMetricsPolicyNameThe chart doesn't render this key in chart 14.x or 15.x, so the key has no effect. Remove the key. To configure the policy, set camunda.data.secondary-storage.<elasticsearch|opensearch>.history.usage-metrics-policy-name.
orchestration.debugThe chart doesn't render this key in chart 14.x or 15.x, so the key has no effect. Remove the key.
orchestration.profilesOverrideThe chart doesn't render this key in chart 14.x or 15.x, so the key has no effect. Remove the key.

Connectors​

Move these keys to connectors.extraConfiguration:

Deprecated keyNotes
connectors.logging.level."io.camunda.connector"logging.level."io.camunda.connector".

Optimize​

Move these keys to optimize.extraConfiguration, except where the notes say otherwise. Entries marked Native config use Optimize's own configuration property names instead of the camunda.* namespace. Set these entries in optimize.extraConfiguration as well:

Deprecated optimize keys
KeyNotes
optimize.logLevel, optimize.upgradeLogLevel, optimize.esLogLevellogging.level.io.camunda.optimize, logging.level.io.camunda.optimize.upgrade, and logging.level.org.elasticsearch. Write each logger name as one key under logging.level.
optimize.profilesspring.profiles.active.
optimize.caches.cloudTenantAuthorizations.{maxSize,minFetchIntervalSeconds}Native config caches.cloudTenantAuthorizations.maxSize and caches.cloudTenantAuthorizations.defaultTtlMillis. The old minFetchIntervalSeconds value is a cache lifetime in milliseconds, so defaultTtlMillis replaces it. These caches apply to multi-tenancy.
optimize.partitionCountNative config zeebe.partitionCount.
optimize.database.{elasticsearch,opensearch}.prefixNative config zeebe.name. Also set orchestration.exporters.zeebe.index.prefix to the same value. If orchestration.exporters.zeebe.index.prefix is unset, the legacy Zeebe exporter uses optimize.database.<elasticsearch|opensearch>.prefix. The exporter doesn't use the extraConfiguration of Optimize. If you migrate only Optimize, Optimize reads indices that the exporter doesn't write.
optimize.multitenancy.enabledMove the key to global.multitenancy.enabled, not to extraConfiguration. This is a platform-wide switch. It also enables multi-tenancy in the Orchestration Cluster and Management Identity. The chart fails the render unless identity.enabled and global.identity.auth.enabled are true. The chart also fails the render unless you configure identity.externalDatabase. See Logical Tenants.

In 8.10, the chart configures Optimize through camunda.security.*. If the Optimize client secret sets existingSecret but no existingSecretKey, the render fails. This check applies to global.identity.auth.optimize.secret and to optimize.security.authentication.oidc.secret. See Render fails because the Optimize client secret has no key.

The chart doesn't configure the OIDC username and client ID claims for Optimize. Before you upgrade, set camunda.security.authentication.oidc.username-claim and client-id-claim through optimize.extraConfiguration to match your identity provider. Otherwise, M2M clients without an Optimize permission may see new permission errors. See Client bearer tokens are now classified for permission checks.

The chart still renders some legacy security keys of Optimize alongside camunda.security.*. Because of this, Optimize logs deprecation warnings on startup, even when you set none yourself. These warnings need no change to your values file.

If you set legacy security properties of Optimize yourself, through optimize.env or optimize.extraConfiguration, Optimize maps the recognized ones at startup. Optimize also logs a deprecation warning. The chart already renders camunda.security.authentication.oidc.* values. These values override a mapped legacy value. Therefore, change those settings with optimize.security.authentication.oidc.* or with an explicit camunda.security.* entry in optimize.extraConfiguration.

Optimize no longer accepts the static API token (api.accessToken or OPTIMIZE_API_ACCESS_TOKEN), unless you set the temporary fallback optimize.security.csl.enabled=false. See component-specific security configuration keys and static API access token.

Camunda Hub​

Move these legacy keys to camundaHub.restapi.extraConfiguration:

Deprecated keysNotes
webModeler.restapi.mail.fromAddresscamunda.hub.mail.from-address. camundaHub.restapi.mail.fromAddress is also deprecated. The chart fails the render when you set none of these keys. See Render fails because the Hub sender address is missing.
webModeler.restapi.mail.fromNamecamunda.hub.mail.from-name.
webModeler.restapi.mail.{smtpHost,smtpPort,smtpUser}spring.mail.host, spring.mail.port, and spring.mail.username.
webModeler.restapi.mail.smtpTlsEnabledspring.mail.properties.mail.smtp.starttls.enable and spring.mail.properties.mail.smtp.starttls.required. Set both. The chart renders both properties from the Helm key.
webModeler.restapi.logging.level.{"io.camunda.modeler","io.grpc"}logging.level.io.camunda.hub and logging.level.io.grpc. The io.camunda.hub logger replaces io.camunda.modeler.

The chart reads these keys from the merged camundaHub.restapi and webModeler.restapi values. It also warns when you set a key under camundaHub.restapi.mail or camundaHub.restapi.logging, but the message names the webModeler.restapi.* key.

Hub authentication settings require no change for this upgrade. Hub continues to authenticate with its own properties. It doesn't use the camunda.security.authentication.oidc.* settings of the Orchestration Cluster. See authentication configuration.

Global​

Move each key to the extraConfiguration of the component that uses it:

Deprecated keyNotes
global.config.requestBodySizeSet spring.servlet.multipart.max-file-size and spring.servlet.multipart.max-request-size on the Orchestration Cluster, Optimize, Management Identity, and the Hub REST API. Also set server.tomcat.max-http-form-post-size on the Orchestration Cluster.
global.zeebeClusterNameSet zeebe.broker.cluster.clusterName on the Orchestration Cluster.
global.documentStore.type.{aws,gcp,inmemory}.storeIdUse the unified camunda.document.* configuration (default-store-id plus the store definition) in orchestration.extraConfiguration. The Orchestration Cluster is the only component that chart 15.x configures from global.documentStore. See Troubleshooting.

Move global.multiregion to orchestration.partitioning​

global.multiregion.regions and global.multiregion.regionId still work in 8.10, but the chart emits a deprecation warning for them. Only the Orchestration Cluster reads them. Therefore, move them to orchestration.partitioning:

8.9 key8.10 key
global.multiregion.regionsorchestration.partitioning.numberOfZones
global.multiregion.regionIdorchestration.partitioning.zoneIndex

Remove the global.multiregion block when you add orchestration.partitioning. If you set both, the render fails.

Keep orchestration.partitioning.scheme at its default, round-robin, for the upgrade to 8.10. The scheme stays fixed for the life of a cluster. If you switch an existing cluster to zone-aware, every broker's identity changes. To convert an existing cluster, first complete the upgrade to 8.10. Then follow Migrate to zone-aware brokers.

Move per-component truststores to global.tls.caBundle​

Chart 15.x deprecates per-component JKS truststores. They still work. The chart emits a deprecation warning when you set one of these keys:

  • orchestration.data.secondaryStorage.elasticsearch.tls.secret.*
  • orchestration.data.secondaryStorage.opensearch.tls.secret.*
  • optimize.database.elasticsearch.tls.secret.*
  • optimize.database.opensearch.tls.secret.*

Supply a PEM-encoded CA bundle through global.tls.caBundle.secret.existingSecret and global.tls.caBundle.secret.existingSecretKey instead. The chart builds the JVM truststore when the pod starts. When you switch, remove the per-component tls.secret entries and any -Djavax.net.ssl.trustStore* flags from javaOpts. If you set a per-component truststore, it overrides global.tls.caBundle for that component. See configure TLS with a CA bundle.

If you keep a per-component truststore for now, set both existingSecret and existingSecretKey. For orchestration.data.secondaryStorage.*.tls.secret, existingSecretKey has no default. Without it, the chart mounts no truststore.

Review the Ingress-nginx annotation defaults​

In chart 14.x, global.ingress.annotations and orchestration.ingress.grpc.annotations had Ingress-nginx annotations as defaults. In chart 15.x, a compatibility shim adds them instead. The key global.compatibility.nginx.renderAnnotations controls this shim, and its default is true.

With the default, the chart renders the same annotations as in 8.9, except ingress.kubernetes.io/rewrite-target, which the chart no longer sets. The chart adds the annotations for any ingressClassName that you use. The chart emits a deprecation warning when the shim adds an annotation.

  • If you use Ingress-nginx, you don't need to change anything for 8.10. To prepare your values file for the shim's removal and silence the warning, set all of the following annotations yourself. In global.ingress.annotations, set ssl-redirect, proxy-buffering, proxy-buffer-size, and proxy-body-size. In orchestration.ingress.grpc.annotations, set ssl-redirect, backend-protocol, and proxy-buffer-size when the gRPC Ingress renders.
  • If you use another Ingress controller, set global.compatibility.nginx.renderAnnotations: false. Also configure the annotations that your controller needs.

For the annotation values and the Contour example, see Ingress-nginx annotation defaults deprecated.

Review changed chart defaults​

The following chart 15.x changes apply on helm upgrade without any change to your values file. Review each change against your deployment.

Set the public issuer URL explicitly​

The default of global.identity.auth.publicIssuerUrl changed from http://localhost:18080/auth/realms/camunda-platform to an empty string. If your 8.9 values file sets neither global.identity.auth.publicIssuerUrl nor global.identity.auth.issuer, the components receive an empty issuer and a relative authorization URI after the upgrade. The chart reports no error. Before you upgrade, set the issuer URL that your users' browsers reach:

global:
identity:
auth:
publicIssuerUrl: https://keycloak.example.com/auth/realms/camunda-platform

Connectors and Management Identity use per-pod ephemeral volumes​

Chart 15.x replaces the persistent volume claim (PVC) that the chart manages for Connectors and Management Identity with a per-pod ephemeral volume. The Web Modeler REST API received the same change. The volume provides storage only for /tmp, so you lose no data.

SettingUpgrade behavior
persistence.enabled: false (default)No change.
persistence.enabled: true, no existingClaimEach pod has its own claim, created with the pod and removed with it. Helm removes the shared claim that it created in 8.9.
persistence.enabled: true, existingClaim setNo change. The pods still mount your existing claim.

This applies to connectors.persistence and identity.persistence. If you set persistence.selector to bind pre-provisioned volumes, provision one matching volume for each pod. Also provision one more matching volume for the extra pod during a rollout.

Connectors probes use the per-probe scheme​

In chart 14.x, the Connectors startup, readiness, and liveness probes used the top-level connectors.scheme. They ignored the per-probe scheme values. In chart 15.x, they use connectors.startupProbe.scheme, connectors.readinessProbe.scheme, and connectors.livenessProbe.scheme. They ignore connectors.scheme.

The per-probe default is empty. An empty value becomes HTTPS when the chart detects that Connectors serves TLS. In all other cases, the value becomes HTTP.

The chart detects TLS from these sources, in this order. First, the chart checks the last SERVER_SSL_ENABLED entry in connectors.env. A value of true or false in this entry wins over the other sources. Second, the chart checks global.tls.connectors.enabled: true. Third, the chart checks server.ssl.enabled: true in connectors.extraConfiguration or connectors.configuration.

  • If you set connectors.scheme, move the value to the per-probe keys.
  • Remove per-probe scheme values that you copied from the chart 14.x defaults (HTTP). Chart 14.x ignored them. Chart 15.x uses them, so a Connectors pod that serves TLS never becomes ready.
  • If Connectors serves TLS, chart 15.x also requires the certificate in your values file. See Render fails because TLS is enabled without a certificate.

Remove environment variables the chart now sets​

Chart 15.x sets these environment variables itself. If your values file sets the same names, remove them from identity.env, optimize.env, or camundaHub.restapi.env. Duplicate names fail helm upgrade when Helm applies the release server-side. By default, Helm v4 applies a release server-side if you installed the release with Helm v4.

ComponentEnvironment variables
Management Identity (global.identity.auth.type: KEYCLOAK)CAMUNDA_CONNECTORS_CLIENT_ID, CAMUNDA_ORCHESTRATION_CLIENT_ID, CAMUNDA_OPTIMIZE_CLIENT_ID
OptimizeVALUES_OPTIMIZE_CLIENT_SECRET when Optimize authenticates and you configure its client secret, and SERVER_SERVLET_CONTEXT_PATH when you set optimize.contextPath
Camunda Hub REST APICAMUNDA_HUB_PUSHER_APPID, CAMUNDA_HUB_PUSHER_KEY, CAMUNDA_HUB_PUSHER_SECRET, and SPRING_MAIL_PASSWORD when you configure camundaHub.restapi.mail.secret

These Hub variables replace RESTAPI_PUSHER_APP_ID, RESTAPI_PUSHER_KEY, RESTAPI_PUSHER_SECRET, and RESTAPI_MAIL_PASSWORD. If camundaHub.restapi.env or webModeler.restapi.env sets one of the old names, the chart emits a warning:

  • For the Pusher variables, remove the entries. The chart always sets the new names. To supply your own Pusher values, see Pin the Hub WebSocket secrets.
  • For RESTAPI_MAIL_PASSWORD, configure camundaHub.restapi.mail.secret and remove the entry. Alternatively, if you don't configure camundaHub.restapi.mail.secret, rename the entry to SPRING_MAIL_PASSWORD.

Management Identity URL includes the Gateway port​

This change applies if you use Gateway API (global.gateway.enabled: true) without the shared Ingress, and you do not set identity.fullURL.

In chart 14.x, the Management Identity URL and the root URL of the Keycloak login client had no port. In chart 15.x, these URLs use the same origin as the other Gateway URLs. The chart adds the Gateway listener port: global.gateway.tls.port when global.gateway.tls.enabled: true, otherwise global.gateway.port. The chart does not add port 443 to HTTPS URLs or port 80 to HTTP URLs.

If clients reach the Gateway on a port that is different from the listener port, set the public port in global.gateway.publicPorts before you upgrade. For example, a LoadBalancer Service sends port 443 to a listener on port 8443:

global:
gateway:
tls:
port: 8443
publicPorts:
https: 443

global.gateway.publicPorts changes only the URLs that the chart generates. It does not change the Gateway listeners or Services.

Review application default changes​

Some 8.10 application defaults change the behavior of a Helm deployment without a change to your values file:

ComponentChangeDetails
Orchestration ClusterThe default memory allocation strategy of RocksDB changes from PARTITION to FRACTION.Default RocksDB memory allocation strategy
OptimizeOptimize no longer imports object variable values by default.Default objectVariable inclusion changed

Migrate deprecated Helm keys to extraConfiguration​

The extraConfiguration value format is the same as in 8.9. If you already use extraConfiguration, you don't need to change the format for this upgrade. For the mechanics and the behavior of each component, see Application configuration and extraConfiguration. The same page gives a worked example of how to move settings into a configuration file.

The following condensed example shows the shape of the migration for the Orchestration Cluster:

# Before (8.9 keys that chart 15.x deprecates)
orchestration:
logLevel: debug
data:
snapshotPeriod: 10m
history:
retention:
enabled: true
minimumAge: 45d

# After (8.10, extraConfiguration)
orchestration:
extraConfiguration:
- file: application-migrated.yaml
content: |
logging:
level:
io.camunda.zeebe: debug
camunda:
data:
snapshot-period: 10m
secondary-storage:
retention:
enabled: true
minimum-age: 45d
elasticsearch:
history:
policy-name: camunda-history-retention-policy

The policy-name entry keeps the ILM policy name the chart rendered in 8.9. For OpenSearch, use opensearch: instead of elasticsearch:.

Example: upgrade values.yaml from 8.9 to 8.10​

This example shows a Helm values.yaml for 8.9 and the same configuration after you migrate it to 8.10. It covers the most common changes: removed global.elasticsearch keys, the Camunda Hub consolidation, a deprecated application configuration key, and the changed issuer URL default. The Hub consolidation includes Hub sizing and pinned Pusher secrets. The Kubernetes Secrets the example references (elasticsearch-credentials, web-modeler-db, and camunda-hub-pusher) must exist before you upgrade.

View example values files
# =========================
# Camunda 8.9 values.yaml
# =========================

global:
host: camunda.example.com

# Removed in 8.10
elasticsearch:
enabled: true
external: true
url:
protocol: https
host: elasticsearch.example.com
port: 443
auth:
username: elastic
secret:
existingSecret: elasticsearch-credentials
existingSecretKey: password

# publicIssuerUrl is not set: the 8.9 default applies
identity:
auth:
console:
redirectUrl: https://camunda.example.com/console

identity:
enabled: true

orchestration:
data:
secondaryStorage:
type: elasticsearch
# Deprecated in 8.10
history:
retention:
enabled: true
minimumAge: 45d

optimize:
enabled: true

console:
enabled: true

webModeler:
enabled: true
restapi:
externalDatabase:
url: jdbc:postgresql://postgres.example.com:5432/web-modeler
username: web-modeler
secret:
existingSecret: web-modeler-db
existingSecretKey: password
mail:
fromAddress: noreply@example.com

Render and test the complete configuration​

After reviewing the toolkit report and completing the manual changes, render your configuration and test the upgrade before upgrading production.

  1. Render the chart and inspect the output for deprecation warnings:

    helm template <RELEASE> camunda/camunda-platform \
    --version <CHART_VERSION> \
    --namespace <NAMESPACE> \
    -f values-8.10.yaml > rendered-8.10.yaml
    grep 'DEPRECATION' rendered-8.10.yaml

    Use the same override files, order, and flags you plan to use for the upgrade. Review and address any rendering errors or deprecation warnings.

  2. Complete the non-production upgrade test listed in the prerequisites, using a copy of your production configuration.

Run the Helm upgrade​

Before upgrading production, complete the non-production test and verify your backups. If you run Web Modeler, follow the Hub backup timing and migration procedure, including stopping writes before the database backup.

If your 8.9 release doesn't run Web Modeler, run the upgrade in one step:

helm repo update
helm upgrade <RELEASE> camunda/camunda-platform \
--version <CHART_VERSION> \
--namespace <NAMESPACE> \
-f values-8.10.yaml

The one-step upgrade applies to a Console-only release after you enable Camunda Hub. To enable Hub, see Deploy Camunda Hub for a Console-only release.

If your release runs Web Modeler, don't run this command. Follow Migrate Web Modeler and Console to Hub instead. The first helm upgrade of that procedure, in the quiesce phase, also upgrades every other component to 8.10.

Migrate Web Modeler and Console to Camunda Hub​

Camunda 8.10 combines the Web Modeler and Console components from 8.9 into Camunda Hub. The component upgrade guide is the authority on how Hub upgrades from 8.9 to 8.10. It explains why the upgrade needs downtime and how the migration changes your data. The steps below apply that procedure to a Helm release with camundaHub.upgrade.phase.

warning

Don't use helm upgrade --rollback-on-failure (or its deprecated alias --atomic) for this upgrade. After the database migration starts, don't return the Helm release to 8.9 before you restore the 8.9 database backup. An 8.9 application isn't compatible with a partially or fully migrated 8.10 database. Flyway doesn't block the startup of the 8.9 application. Therefore, the application can report that it's ready while requests that use removed tables or columns fail.

The camundaHub.upgrade.phase value controls the Hub workloads during the migration:

PhaseREST API replicasWebSockets replicasServes traffic
quiesce00No
migrate10No
normalThe configured replica count1Yes

The Hub Services select only pods in the normal phase. The migration pod is therefore unavailable to user traffic.

The commands below use the chart's default resource names. If you set fullnameOverride or nameOverride under camundaHub or webModeler, list the names with kubectl -n <NAMESPACE> get deployment -l app.kubernetes.io/instance=<RELEASE>. Also list the names with this command if your release name contains web-modeler.

Pin the Hub WebSocket secrets​

The migration runs helm upgrade three times. If you don't set the Pusher secrets, the chart generates new random values on every upgrade. The REST API and WebSockets pods read these values only when they start. Therefore, a pod that restarts after a later upgrade can have different values from the other pod. Different values in the two pods break WebSocket authentication.

Before you start, create a Kubernetes Secret that holds both values. Then reference the Secret. Any values work, because the REST API and WebSockets pods read the same Secret. The Secret must exist with the named keys before the first helm upgrade. The Hub pods don't start without the Secret.

camundaHub:
restapi:
pusher:
secret:
existingSecret: camunda-hub-pusher
existingSecretKey: app-secret
client:
secret:
existingSecret: camunda-hub-pusher
existingSecretKey: app-key

Stop Web Modeler and Console workloads​

Upgrade the release to 8.10 in the quiesce phase. This helm upgrade also upgrades every other component in the release to 8.10:

helm repo update
helm upgrade <RELEASE> camunda/camunda-platform \
--version <CHART_VERSION> \
--namespace <NAMESPACE> \
-f values-8.10.yaml \
--set camundaHub.upgrade.phase=quiesce \
--wait \
--timeout 10m

Check that both Web Modeler Deployments show zero desired and available replicas:

kubectl -n <NAMESPACE> get deployment \
<RELEASE>-web-modeler-restapi \
<RELEASE>-web-modeler-websockets

The Deployment status doesn't count terminating pods. Check that no Web Modeler pods remain. Continue when the command returns No resources found:

kubectl -n <NAMESPACE> get pods \
-l app.kubernetes.io/instance=<RELEASE>,app.kubernetes.io/name=web-modeler

Also check that the 8.9 Console Deployment and pods no longer exist. Helm removes the Console Deployment during this upgrade, so the first command returns NotFound and the second command returns No resources found:

kubectl -n <NAMESPACE> get deployment <RELEASE>-console
kubectl -n <NAMESPACE> get pods \
-l app.kubernetes.io/instance=<RELEASE>,app.kubernetes.io/component=console

Stop any external processes that write to the Hub database. Check that no Hub writers remain before you continue.

Back up the Hub database​

Create a vendor-native backup of the Hub database after you quiesce Hub. This backup is the recovery point if the migration fails or you must return to 8.9. Use the backup tool for your database platform, such as pg_dump for PostgreSQL. See RDBMS backup and restore guidance.

Don't continue until you check that you can restore the Hub database backup.

Run the database migration​

Set the release to the migrate phase:

helm upgrade <RELEASE> camunda/camunda-platform \
--version <CHART_VERSION> \
--namespace <NAMESPACE> \
-f values-8.10.yaml \
--set camundaHub.upgrade.phase=migrate \
--set camundaHub.restapi.livenessProbe.enabled=false \
--set camundaHub.restapi.startupProbe.enabled=false \
--wait \
--timeout 10m

The chart disables the REST API liveness and startup probes by default. Keep these probes disabled for the migrate phase. Also keep a probe disabled if you enabled it under the legacy webModeler.restapi.* keys. The probe endpoint isn't reachable until the migration completes. Therefore, Kubernetes restarts the container after failureThreshold failed probes.

Measure the migration time on a test system that has a copy of your data. Set --timeout to a value longer than that time. If helm upgrade exceeds that timeout, the migration pod continues to migrate. In this case, check the logs of the migration pod before you do anything else.

The single Hub REST API pod runs the database migration during startup. The Hub Service doesn't route to the pod. Wait until the pod is ready:

kubectl -n <NAMESPACE> rollout status \
deployment/<RELEASE>-web-modeler-restapi \
--timeout=10m

Before you restore traffic, check the migrated Hub data. First, check the REST API logs:

kubectl -n <NAMESPACE> logs \
deployment/<RELEASE>-web-modeler-restapi

For the Flyway log entries that show the progress and the result of the migration, see Database migration. For the changes that the migration makes to your Hub data, see Data migration.

The migration also carries the clusters that your projects used into Hub as environments. It assigns the environments to their workspaces. See environments.

The Hub Services don't route to the migration pod. To check the migrated data in the Hub UI before you restore traffic, forward a local port to the pod. Use kubectl -n <NAMESPACE> port-forward deployment/<RELEASE>-web-modeler-restapi <LOCAL_PORT>:<POD_PORT>.

If the migration fails:

  1. Set camundaHub.upgrade.phase to quiesce again. Wait until both Hub Deployments reach zero replicas. See Stop Web Modeler and Console workloads for the procedure.
  2. Check that no other process that can write to the Hub database runs.
  3. Restore the 8.9 Hub database backup. Check the backup. For the procedure, see Backup and restore Hub data.
  4. Fix the cause of the failure. Repeat the migrate phase.

To return the whole release to 8.9 instead, restore the Hub database backup. Then find the last 8.9 revision with helm history <RELEASE> --namespace <NAMESPACE>. Then run helm rollback <RELEASE> <REVISION> --namespace <NAMESPACE>. The rollback applies to every component in the release.

The quiesce upgrade already moved the Orchestration Cluster and the other components to 8.10. Camunda doesn't support minor downgrades. Therefore, also restore the backups you created of those components before the upgrade. See version compatibility checks.

Restore Hub traffic​

After you check the migration, set the release to the normal phase:

helm upgrade <RELEASE> camunda/camunda-platform \
--version <CHART_VERSION> \
--namespace <NAMESPACE> \
-f values-8.10.yaml \
--set camundaHub.upgrade.phase=normal \
--wait \
--timeout 10m

Wait until both Hub workloads are ready:

kubectl -n <NAMESPACE> rollout status \
deployment/<RELEASE>-web-modeler-restapi \
--timeout=10m
kubectl -n <NAMESPACE> rollout status \
deployment/<RELEASE>-web-modeler-websockets \
--timeout=10m
note

The lifecycle phases currently need you to follow this sequence. If you select normal before the migration completes, the chart doesn't yet prevent this.

For a fresh 8.10 installation, leave camundaHub.upgrade.phase at its default value, normal. The quiesce and migrate phases apply only when you upgrade an existing 8.9 Web Modeler database. Console has no database in 8.9.

Migrate document-store cloud credentials​

This migration applies only when a component uses credentials propagated from global.documentStore.type.* for a separate cloud integration. Configure replacement credentials only on each affected component. Don't copy document-store credentials to components that don't independently need cloud access. The migration applies when global.documentStore.type.aws.enabled or global.documentStore.type.gcp.enabled is true, or when global.documentStore.activeStoreId is aws or gcp. Chart 15.x emits no warning when these credentials disappear from a component.

note

optimize.env, camundaHub.restapi.env, and identity.env support Helm's tpl templating (for example, {{ .Release.Name }}). connectors.env and every <component>.envFrom don't support tpl templating. The chart renders them as plain YAML.

For Camunda Hub, a list that you add under camundaHub.restapi replaces the matching webModeler.restapi list. Examples of such lists are env, extraVolumes, and extraVolumeMounts. Move your existing entries into the matching camundaHub.restapi list.

AWS - Static access key / secret key​

Connectors: The default credentials chain of the AWS SDK uses these credentials for connector tasks (Lambda, SQS, SNS, DynamoDB, Bedrock, Textract).

connectors:
env:
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: connectors-aws-credentials
key: accessKeyId
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: connectors-aws-credentials
key: secretAccessKey

Optimize: Optimize signs AWS OpenSearch requests with these credentials when optimize.database.opensearch.aws.enabled is true. In 8.9, the chart also accepted global.opensearch.aws.enabled. Chart 15.x rejects this key.

optimize:
env:
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: optimize-aws-credentials
key: accessKeyId
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: optimize-aws-credentials
key: secretAccessKey
- name: AWS_REGION
valueFrom:
secretKeyRef:
name: optimize-aws-credentials
key: region
note

Optimize catches its credential resolution failures and silently uses Basic authentication instead. After you migrate, check the OpenSearch connection. Don't expect a startup error.

Camunda Hub:

camundaHub:
restapi:
env:
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: camunda-hub-aws-credentials
key: accessKeyId
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: camunda-hub-aws-credentials
key: secretAccessKey
- name: AWS_REGION
valueFrom:
secretKeyRef:
name: camunda-hub-aws-credentials
key: region

Any of the three components can load the variables at once through envFrom instead. This option works if the Secret's data keys already have the names AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. Optimize and Hub also need a data key named AWS_REGION.

connectors: # (or optimize: / camundaHub.restapi:)
envFrom:
- secretRef:
name: <component>-aws-credentials

AWS - IRSA​

Annotate each component's own service account:

connectors:
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/connectors-role

optimize:
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/optimize-role

camundaHub:
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/camunda-hub-role

AWS - EKS Pod Identity​

Create an EKS Pod Identity association for each component service account instead of the eks.amazonaws.com/role-arn annotation. With the default names, the service accounts are <RELEASE>-connectors, <RELEASE>-optimize, <RELEASE>-identity, and <RELEASE>-web-modeler for Camunda Hub. The Hub REST API and WebSockets pods share the <RELEASE>-web-modeler service account.

For both IRSA and EKS Pod Identity, set AWS_REGION explicitly for Optimize and Hub. EKS Pod Identity provides credentials but no region. The IRSA webhook injects only the region of the cluster. It injects this region only when the webhook has a region configured. Connectors doesn't need AWS_REGION because its element templates contain the region for each task.

GCP​

Connectors:

The examples below use gcp-credentials as the Secret name. They expect the Secret's data key to have the name service-account.json. Replace gcp-credentials with the name of your Secret.

If your 8.9 global.documentStore.type.gcp.secret.existingSecretKey used another key, map that key to service-account.json with secret.items. Alternatively, update GOOGLE_APPLICATION_CREDENTIALS to the mounted filename. If you changed global.documentStore.type.gcp.mountPath or global.documentStore.type.gcp.fileName, use those values for mountPath and in GOOGLE_APPLICATION_CREDENTIALS.

connectors:
env:
- name: GOOGLE_APPLICATION_CREDENTIALS
value: /var/secrets/gcp/service-account.json
extraVolumeMounts:
- name: connectors-gcp-credentials
mountPath: /var/secrets/gcp
readOnly: true
extraVolumes:
- name: connectors-gcp-credentials
secret:
secretName: gcp-credentials

Camunda Hub REST API:

camundaHub:
restapi:
env:
- name: GOOGLE_APPLICATION_CREDENTIALS
value: /var/secrets/gcp/service-account.json
extraVolumeMounts:
- name: camunda-hub-gcp-credentials
mountPath: /var/secrets/gcp
readOnly: true
extraVolumes:
- name: camunda-hub-gcp-credentials
secret:
secretName: gcp-credentials

Workload Identity (GKE) is the equivalent of IRSA. It uses an annotation in <component>.serviceAccount.annotations:

connectors: # (or camundaHub:)
serviceAccount:
annotations:
iam.gke.io/gcp-service-account: <gsa-name>@<project-id>.iam.gserviceaccount.com

Azure​

Optimize and Camunda Hub need no migration because the chart never connected global.documentStore.type.azure.* to them. Chart 14.8.0 and earlier also rendered these settings into Connectors. However, Connectors has no consumer for these settings, so it needs no migration either. Only the document store feature itself reads these settings. The Orchestration Cluster owns this feature.

Identity​

Chart 14.8.0 and earlier passed the document-store AWS credentials, AWS_REGION, and GCP credentials to Management Identity. Chart 14.8.1 and later, and chart 15.x, don't pass them. If you configured Aurora/RDS IAM authentication manually through identity.env and used them, keep the datasource override.

Then supply credentials in one of these ways. For static credentials, supply them through identity.env or identity.envFrom. For IRSA, annotate identity.serviceAccount. For EKS Pod Identity, create an association.

The AWS JDBC Wrapper takes the region for the IAM token from the database hostname. Set the iamRegion parameter of the wrapper when the hostname doesn't contain the region.

Not affected​

  • Orchestration Cluster continues to own global.documentStore.type.* for the document store feature itself. AWS, GCP, and in-memory stores need no change if you use these keys only for that feature.

    For Azure Blob Storage, the chart binds global.documentStore.type.azure.connectionString to camunda.document.azure.<activeStoreId>.connection-string. This binding happens only when you set the connection string Secret and orchestration.extraConfiguration declares the store under camunda.document.azure.<activeStoreId> (in lowercase). Chart 14.x always set the DOCUMENT_STORE_<STORE_ID>_CONNECTION_STRING environment variable instead. See Azure Blob Storage configuration.

Monitor and validate the upgrade​

After you trigger the Helm upgrade, monitor the rollout to check that all pods return to a healthy state.

Watch pod rollout progress​

kubectl -n <NAMESPACE> get pods -w

You should see pods terminate and restart with updated images.

Inspect logs (if required)​

kubectl -n <NAMESPACE> logs <POD_NAME> --previous

Monitor migration progress​

There are two ways to monitor the migration status of the Orchestration Cluster:

Public Cluster API​

The public Cluster API endpoint for upgrade readiness, /cluster/v2/status/upgrade, returns the overall upgrade-readiness status.

{
"status": "MIGRATED"
}

Management API​

The Management API endpoint for upgrade readiness returns more detail about the overall upgrade status, including details for each physical tenant and condition.

Validate the upgrade​

  1. Check that all pods are healthy and run 8.10.x images:

    kubectl -n <NAMESPACE> get pods
    kubectl -n <NAMESPACE> get pods -o jsonpath="{range .items[*]}{.metadata.name}{':\t'}{range .spec.containers[*]}{.image}{'\n'}{end}{end}"
  2. Check the helm upgrade output for [camunda][warning] DEPRECATION messages. Each message names a deprecated key and tells you where to move it or that you can remove it. Most messages also state when the chart removes the key (chart v16, Camunda 8.11). Helm prints these messages with the release notes, so --hide-notes and global.createReleaseInfo: false hide them. The chart also writes them to the <RELEASE-FULLNAME>-warnings ConfigMap.

  3. Check access to Camunda components. Check authentication and authorization behavior. Check that your workers can still poll and complete jobs.

  4. In Camunda Hub, click Environments in the left navigation, and confirm that the expected environments appear with the correct status. Assign environments to any workspace that you create after the upgrade. See environments.

Troubleshooting​

Upgrade failed due to missing secrets​

If your upgrade fails because credentials are missing, see Extract plaintext values and reference them as Kubernetes Secrets.

Upgrade failed with secondary storage validation error​

If Helm fails with a validation error about the secondary storage type, set the type explicitly:

orchestration:
data:
secondaryStorage:
type: elasticsearch # or "opensearch" or "rdbms"

Then set the connection settings for that backend, for example orchestration.data.secondaryStorage.elasticsearch.url. The Elasticsearch default uses <RELEASE>-elasticsearch, which chart 15.x doesn't deploy.

Alternatively, if you don't need secondary storage, set global.noSecondaryStorage: true. This setting disables Operate, Tasklist, and Optimize.

Backwards-compatible audiences replace the audience list​

The deprecated orchestration.security.authentication.oidc.backwardsCompatibleAudiences appended its values to the default audiences. However, its target, camunda.security.authentication.oidc.audiences, replaces the whole list. If you migrate the key verbatim, the Orchestration Cluster accepts only your extra audience and rejects tokens for the default audiences. The gRPC API reports this rejection as UNAUTHENTICATED: Invalid bearer token.

The chart's default audiences are orchestration (the client ID) and orchestration-api. When you enable Camunda Hub, the default audiences also include web-modeler-api. List the default audiences alongside your backwards-compatible audience in audiences.

Initialization authorizations report "No permissionTypes provided"​

If the Orchestration Cluster pod fails to start with IdentityInitializationException: Cannot initialize configured authorizations for tenant 'default': followed by the line - No permissionTypes provided, an authorization entry has no permissions list. Under camunda.security.initialization.authorizations, the permission list field is permissions, not permissionTypes.

Custom document store ID​

You can't use a non-default global.documentStore.type.inmemory.storeId (or aws/gcp) through the deprecated key alone. The reason is that global.documentStore.activeStoreId (the store type) sets the default store ID. The custom store ID never sets it. As a result, the app fails with Default document store ID does not match any configured document store.

Migrate the whole document configuration to camunda.document.* (default-store-id plus the store definition) in orchestration.extraConfiguration. The Orchestration Cluster is the only component that chart 15.x configures from global.documentStore.

Multi-tenancy with an unprotected API​

You can't combine camunda.security.multi-tenancy.checks-enabled: true with camunda.security.authentication.unprotected-api: true. If you do, the Orchestration Cluster pod fails with Multi-tenancy is enabled ... but the API is unprotected. Protect the API when you enable multi-tenancy.

Render fails because a values key has been removed​

If helm upgrade fails with [camunda][error] The Helm values file key "<KEY>" has been removed., your values file still sets a key that chart 15.x no longer accepts. The chart checks for these keys before it changes any workloads. Remove or replace the key. For details, see Remove keys rejected by chart 15.x.

Render fails because the Optimize client secret has no key​

If helm upgrade fails with [camunda][error] Optimize with OIDC authentication requires an existingSecretKey alongside its existingSecret, the Optimize client secret references a Kubernetes Secret but doesn't name the key inside the Secret. Without the key, the chart would drop the client secret from the Optimize Deployment.

Set the key next to the Secret name. If you reference the Secret in global.identity.auth.optimize.secret.existingSecret, set global.identity.auth.optimize.secret.existingSecretKey. If you reference the Secret in optimize.security.authentication.oidc.secret.existingSecret, set optimize.security.authentication.oidc.secret.existingSecretKey. Alternatively, supply VALUES_OPTIMIZE_CLIENT_SECRET yourself through optimize.env. Another option is to list VALUES_OPTIMIZE_CLIENT_SECRET in optimize.security.authentication.oidc.envFromProvides.

Render fails because Optimize sets server.ssl​

If helm upgrade fails with [camunda][error] optimize.env sets [...], which the Optimize server does not support. or [camunda][error] optimize.configuration or optimize.extraConfiguration declares server.ssl, which the Optimize server does not support., your values file sets SERVER_SSL_* environment variables or server.ssl.* properties for Optimize. The chart rejects them regardless of their value.

Optimize installs its own HTTPS connector from container.keystore.*. server.ssl.* adds a second SSL host configuration named _default_ to the same connector. As a result, Tomcat aborts at startup.

Remove the SERVER_SSL_* environment variables and the server.ssl.* properties. To serve TLS from Optimize, set global.tls.optimize.enabled: true. Set global.tls.optimize.cert.secret.existingSecret to a Secret that holds a PKCS12 keystore (keystore.p12) and its password (keystore-password). Optimize doesn't support PEM certificates or a key alias.

Render fails because the Hub sender address is missing​

If helm upgrade fails with The value 'webModeler.restapi.mail.fromAddress' is required, Camunda Hub has no sender address for emails. Set camunda.hub.mail.from-address in a camundaHub.restapi.extraConfiguration file that Spring imports. The chart finds the key as nested or dotted YAML in any document of the file, and in a .properties file. The chart also accepts the legacy camunda.modeler.mail.from-address, camundaHub.restapi.mail.fromAddress, and webModeler.restapi.mail.fromAddress.

Render fails because both multi-region blocks are set​

If helm upgrade fails with [camunda][error] orchestration.partitioning and global.multiregion are both configured., your values file sets the deprecated global.multiregion block and its replacement. Keep orchestration.partitioning. Remove global.multiregion. See Move global.multiregion to orchestration.partitioning.

Render fails because TLS is enabled without a certificate​

If helm upgrade fails with [camunda][error] Orchestration REST TLS is enabled but no server cert is configured., chart 15.x detected TLS for the Orchestration Cluster REST API but found no certificate. In order of precedence, the chart detects REST TLS from SERVER_SSL_ENABLED in orchestration.env, global.tls.orchestration.rest.enabled, and a nested server.ssl.enabled key in orchestration.extraConfiguration or orchestration.configuration. Set global.tls.orchestration.rest.cert.secret.existingSecret. Alternatively, configure SERVER_SSL_KEY_STORE or SERVER_SSL_CERTIFICATE manually in orchestration.env, together with the matching volumes. Another option is to remove the TLS setting.

The chart runs separate checks for the gRPC API and for Connectors:

  • The gRPC check fails with [camunda][error] Orchestration gRPC TLS is enabled but no server cert is configured. when CAMUNDA_API_GRPC_SSL_ENABLED, global.tls.orchestration.grpc.enabled, or a nested camunda.api.grpc.ssl.enabled key enables TLS and you don't set global.tls.orchestration.grpc.cert.secret.existingSecret.
  • The Connectors check fails with [camunda][error] Connectors TLS is enabled but no server cert is configured. when SERVER_SSL_ENABLED in connectors.env, global.tls.connectors.enabled, or a nested server.ssl.enabled key enables TLS. To fix the failure, set global.tls.connectors.enabled: true together with global.tls.connectors.cert.secret.existingSecret.

See Orchestration Cluster TLS modes.

Next steps​

This upgrade keeps your deployment in the chart's default combined topology. In this topology, one Helm release runs every enabled component. The upgrade doesn't change your release layout.

For a new production deployment, the baseline topology of Camunda 8.10 is different. It has one Hub release and one release for each Orchestration Cluster. It also has one Optimize release for each Physical Tenant. See Camunda 8.10 deployment topology.

To move an existing deployment to that topology, you do a separate operation. This operation needs its own data, storage, and rollback planning. First, complete this version upgrade. Then, see move from a combined release to the split topology.