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.
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.
Prerequisites
Before you upgrade, make sure you meet these prerequisites:
| Prerequisite | Description |
|---|---|
Confirm 8.9.x baseline | Check 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 version | Camunda 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 eligibility | Review Prepare for upgrade to check upgrade eligibility and to check infrastructure compatibility for 8.10. |
| Confirm Helm chart support | Review 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 subcharts | If 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. |
| Backups | Create 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.yaml | Review your existing values.yaml for keys that chart 15.x rejects, deprecated Helm keys, and changed chart defaults. |
| Plan the Camunda Hub migration | If 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 upgrade | Test 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:
- Run the Camunda Helm Toolkit to migrate and validate override files.
- Review the report and complete the version-specific manual actions.
- Render and test the complete, layered configuration in non-production.
- Back up data and run the Helm upgrade.
- 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.
- Keep a copy of your original 8.9 overrides. Run the toolkit with source
8.9and target8.10to createvalues-8.10.yaml. For layered overrides, migrate each file separately and retain the Helm-forder. - Inspect the migrated YAML and act on the report. Resolve errors before using the output and review warnings for manual actions.
- 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
camundaHubcan't remove a key thatwebModelersets. - Lists don't merge. A list under
camundaHub, such ascamundaHub.restapi.env,extraVolumes,extraConfiguration,tolerations, orinitContainers, replaces the whole list underwebModeler. When you move a list, move all of its entries. - If you set a scalar under
camundaHubwherewebModelerhas 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:
| Setting | Helm key |
|---|---|
| External PostgreSQL database | camundaHub.restapi.externalDatabase.*. The chart doesn't check this setting at render time. |
| Sender address for Hub emails | camunda.hub.mail.from-address in camundaHub.restapi.extraConfiguration. The render fails without this setting. |
| SMTP server for Hub emails | spring.mail.* in camundaHub.restapi.extraConfiguration. Hub sends no emails without this setting. |
| Public URL for the login callback | global.identity.auth.camundaHub.redirectUrl. It replaces global.identity.auth.console.redirectUrl. |
| Path Hub is served on | camundaHub.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 key | 8.10 key or action |
|---|---|
console.resources | camundaHub.restapi.resources. See Review Hub REST API resources. |
console.env, console.envFrom | camundaHub.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.dnsConfig | Use 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.contextPath | No equivalent. Hub serves Console's pages on camundaHub.contextPath. |
console.configuration, console.extraConfiguration, console.overrideConfiguration | Cluster 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.pullSecrets | camundaHub.image.registry, camundaHub.image.pullSecrets. |
console.image.repository, console.image.tag, console.image.digest | No 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.realm | No 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 image | 8.10 image |
|---|---|
camunda/web-modeler-restapi:8.9.x | camunda/hub:8.10.x |
camunda/web-modeler-websockets:8.9.x | camunda/hub-websockets:8.10.x |
camunda/console:8.9.x | The 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:
| Pod | Requests (CPU / memory) | Limits (CPU / memory) |
|---|---|---|
| 8.9 Console | 1000m / 1Gi | 2000m / 2Gi |
| 8.9 Web Modeler REST API | 900m / 1280Mi | 1800m / 2560Mi |
| 8.10 Hub REST API | 900m / 1280Mi | 1800m / 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:
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:
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:
- 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.
- Point the 8.9 release at the external database. Verify that Management Identity or Web Modeler works with it.
- Before you remove the bundled database, protect its volume. Do these steps:
- Examine the reclaim policy of its PersistentVolume and the
persistentVolumeClaimRetentionPolicyof its StatefulSet. - Set
persistentVolumeReclaimPolicyof the PersistentVolume toRetain. - Make a backup and verify that you can restore it.
- Examine the reclaim policy of its PersistentVolume and the
- Remove the bundled database.
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.sidecarsoridentity.initContainersand 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.existingClaimwithpersistence.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.
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 yourextraConfigurationitself. 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 ascamunda.data.snapshot-period. Therefore, write migrated properties as nested YAML. - The chart doesn't process
extraConfigurationcontent as a template. Write final values instead of expressions such as{{ .Release.Name }}. - If you set
orchestration.configuration, this setting replaces the generatedapplication.yaml, including itsspring.config.importlist. As a result, the chart doesn't import yourextraConfigurationfiles, unless your file imports them. - Some chart defaults differ from the application defaults. For example,
orchestration.cpuThreadCountandorchestration.ioThreadCounthave the chart default3and the application default2. The keyorchestration.history.rolloverBatchSizehas the chart default100and the application default500. 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.
Connectors
Move these keys to connectors.extraConfiguration:
| Deprecated key | Notes |
|---|---|
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:
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 keys | Notes |
|---|---|
webModeler.restapi.mail.fromAddress | camunda.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.fromName | camunda.hub.mail.from-name. |
webModeler.restapi.mail.{smtpHost,smtpPort,smtpUser} | spring.mail.host, spring.mail.port, and spring.mail.username. |
webModeler.restapi.mail.smtpTlsEnabled | spring.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 key | Notes |
|---|---|
global.config.requestBodySize | Set 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.zeebeClusterName | Set zeebe.broker.cluster.clusterName on the Orchestration Cluster. |
global.documentStore.type.{aws,gcp,inmemory}.storeId | Use 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 key | 8.10 key |
|---|---|
global.multiregion.regions | orchestration.partitioning.numberOfZones |
global.multiregion.regionId | orchestration.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, setssl-redirect,proxy-buffering,proxy-buffer-size, andproxy-body-size. Inorchestration.ingress.grpc.annotations, setssl-redirect,backend-protocol, andproxy-buffer-sizewhen 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.
| Setting | Upgrade behavior |
|---|---|
persistence.enabled: false (default) | No change. |
persistence.enabled: true, no existingClaim | Each 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 set | No 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
schemevalues 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.
| Component | Environment variables |
|---|---|
Management Identity (global.identity.auth.type: KEYCLOAK) | CAMUNDA_CONNECTORS_CLIENT_ID, CAMUNDA_ORCHESTRATION_CLIENT_ID, CAMUNDA_OPTIMIZE_CLIENT_ID |
| Optimize | VALUES_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 API | CAMUNDA_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, configurecamundaHub.restapi.mail.secretand remove the entry. Alternatively, if you don't configurecamundaHub.restapi.mail.secret, rename the entry toSPRING_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:
| Component | Change | Details |
|---|---|---|
| Orchestration Cluster | The default memory allocation strategy of RocksDB changes from PARTITION to FRACTION. | Default RocksDB memory allocation strategy |
| Optimize | Optimize 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
- 8.9 values.yaml (before)
- 8.10 values-8.10.yaml (after)
# =========================
# 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
# =========================
# Camunda 8.10 values-8.10.yaml
# =========================
global:
host: camunda.example.com
identity:
auth:
# The 8.10 default is empty; set it explicitly
publicIssuerUrl: https://camunda.example.com/auth/realms/camunda-platform
# global.identity.auth.console removed; it has no effect in 8.10
identity:
enabled: true
orchestration:
data:
secondaryStorage:
type: elasticsearch
elasticsearch:
url: https://elasticsearch.example.com:443
auth:
username: elastic
secret:
existingSecret: elasticsearch-credentials
existingSecretKey: password
extraConfiguration:
- file: application-migrated.yaml
content: |
camunda:
data:
secondary-storage:
retention:
enabled: true
minimum-age: 45d
elasticsearch:
history:
policy-name: camunda-history-retention-policy
optimize:
enabled: true
database:
elasticsearch:
enabled: true
external: true
url:
protocol: https
host: elasticsearch.example.com
port: 443
auth:
username: elastic
secret:
existingSecret: elasticsearch-credentials
existingSecretKey: password
# Replaces console and webModeler
camundaHub:
enabled: true
restapi:
# Sized for Console and the Web Modeler REST API together
resources:
requests:
cpu: 1900m
memory: 2304Mi
limits:
cpu: 3800m
memory: 4608Mi
externalDatabase:
url: jdbc:postgresql://postgres.example.com:5432/web-modeler
username: web-modeler
secret:
existingSecret: web-modeler-db
existingSecretKey: password
extraConfiguration:
- file: application-mail.yaml
content: |
camunda:
hub:
mail:
from-address: noreply@example.com
pusher:
secret:
existingSecret: camunda-hub-pusher
existingSecretKey: app-secret
client:
secret:
existingSecret: camunda-hub-pusher
existingSecretKey: app-key
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.
-
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.yamlUse the same override files, order, and flags you plan to use for the upgrade. Review and address any rendering errors or deprecation warnings.
-
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.
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:
| Phase | REST API replicas | WebSockets replicas | Serves traffic |
|---|---|---|---|
quiesce | 0 | 0 | No |
migrate | 1 | 0 | No |
normal | The configured replica count | 1 | Yes |
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:
- Set
camundaHub.upgrade.phasetoquiesceagain. Wait until both Hub Deployments reach zero replicas. See Stop Web Modeler and Console workloads for the procedure. - Check that no other process that can write to the Hub database runs.
- Restore the 8.9 Hub database backup. Check the backup. For the procedure, see Backup and restore Hub data.
- Fix the cause of the failure. Repeat the
migratephase.
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
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.
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
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.connectionStringtocamunda.document.azure.<activeStoreId>.connection-string. This binding happens only when you set the connection string Secret andorchestration.extraConfigurationdeclares the store undercamunda.document.azure.<activeStoreId>(in lowercase). Chart 14.x always set theDOCUMENT_STORE_<STORE_ID>_CONNECTION_STRINGenvironment 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
-
Check that all pods are healthy and run
8.10.ximages:kubectl -n <NAMESPACE> get pods
kubectl -n <NAMESPACE> get pods -o jsonpath="{range .items[*]}{.metadata.name}{':\t'}{range .spec.containers[*]}{.image}{'\n'}{end}{end}" -
Check the
helm upgradeoutput for[camunda][warning] DEPRECATIONmessages. 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-notesandglobal.createReleaseInfo: falsehide them. The chart also writes them to the<RELEASE-FULLNAME>-warningsConfigMap. -
Check access to Camunda components. Check authentication and authorization behavior. Check that your workers can still poll and complete jobs.
-
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.whenCAMUNDA_API_GRPC_SSL_ENABLED,global.tls.orchestration.grpc.enabled, or a nestedcamunda.api.grpc.ssl.enabledkey enables TLS and you don't setglobal.tls.orchestration.grpc.cert.secret.existingSecret. - The Connectors check fails with
[camunda][error] Connectors TLS is enabled but no server cert is configured.whenSERVER_SSL_ENABLEDinconnectors.env,global.tls.connectors.enabled, or a nestedserver.ssl.enabledkey enables TLS. To fix the failure, setglobal.tls.connectors.enabled: truetogether withglobal.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.