For the complete documentation index, see llms.txt.
Skip to main content
Version: 8.10 (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: upgrade to the latest patch of your current minor first, then upgrade one minor version at a time without skipping minors. Skipping a minor version fails the schema compatibility check and blocks startup. Upgrading to the latest patch of each minor is strongly recommended for fix coverage, but the check itself compares minor versions.

See version compatibility checks.

Prerequisites​

Before upgrading, ensure you have met the following prerequisites:

PrerequisiteDescription
Confirm 8.9.x baselineConfirm your deployment is running an 8.9.x version before upgrading to 8.10. If you are upgrading from a version earlier than 8.9, upgrade one minor at a time. See upgrade Helm chart. Upgrading to the latest available 8.9.x patch first is strongly recommended 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 confirm upgrade eligibility and complete any required pre-upgrade actions for 8.10.
Confirm Helm chart supportReview the Camunda Helm chart version matrix and confirm the chart version deploying 8.10 is supported for your Kubernetes and Helm client versions.
BackupsCreate and verify backups for your Camunda data. See Backup and restore.
Check your values.yamlReview your existing values.yaml for the deprecated application configuration Helm keys that move to extraConfiguration in 8.10.
Test upgradeTest the upgrade in a non-production environment using a copy of your production configuration.

Create your 8.10 values file​

Use your existing 8.9 configuration as the starting point for the upgrade.

  1. Create values-8.10.yaml from your existing overrides. Copy the original file, or use the Camunda Helm Toolkit with source 8.9 and target 8.10 to migrate supported settings. Review its findings and complete the required configuration changes below; toolkit support for 8.10 is preliminary.

  2. Download the default values for the Camunda 8.10 Helm chart:

    helm repo update
    helm show values camunda/camunda-platform --version <CHART_VERSION> > values-8.10-default.yaml

    To identify the latest available 15.x chart version, including prereleases, run:

    helm search repo camunda/camunda-platform --versions --devel \
    | awk '$2 ~ /^15\./ { print; exit }'
  3. Update values-8.10.yaml using the sections below.

  4. Compare values-8.10.yaml with values-8.10-default.yaml to identify any remaining new options, changed defaults, and deprecated settings before running helm upgrade.

Update your values file to 8.10​

Consolidate Console and Web Modeler into Camunda Hub​

Camunda 8.10 consolidates Console and Web Modeler into Camunda Hub. Replace all console and webModeler top-level configurations with camundaHub.

note

Existing webModeler.* settings remain fallback values, but migrate them to the equivalent flattened camundaHub.* paths. Do not nest settings under camundaHub.webModeler or camundaHub.console.

Enable Hub​

Console and Web Modeler are no longer standalone deployments. The camunda/hub image serves both feature sets.

Replace the legacy enablement keys with camundaHub.enabled, and 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 console.enabled and webModeler.enabled keys remain compatibility shims in 8.10 and emit deprecation warnings.

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

The standalone camunda/console image is no longer deployed. Configure the Hub repositories under camundaHub.restapi.image.repository and camundaHub.websockets.image.repository.

Because Console now runs in the Hub REST API pod, review camundaHub.restapi.resources after upgrading and adjust the requests and limits if the pod is throttled or runs out of memory.

Remove keys rejected by chart 15.x​

Chart 15.x rejects removed values before changing any workloads. Update or remove these values before upgrading:

Removed keys
Removed keyReplacement or action
global.ingress.hostUse global.host.
global.identity.keycloak.auth.existingSecretUse global.identity.keycloak.auth.secret.existingSecret.
global.identity.keycloak.auth.existingSecretKeyUse global.identity.keycloak.auth.secret.existingSecretKey.
global.elasticsearch.*Use optimize.database.elasticsearch.* for Optimize and orchestration.data.secondaryStorage.elasticsearch.* for the Orchestration Cluster. See the migration mapping below.
global.opensearch.*Use optimize.database.opensearch.* for Optimize and 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. See Migrate from Bitnami charts.
webModelerPostgresqlMigrate the Camunda Hub database to external PostgreSQL and configure camundaHub.restapi.externalDatabase.
elasticsearchMigrate to external Elasticsearch or OpenSearch and configure the component-specific secondary storage values.

Migrate global.elasticsearch and global.opensearch​

The global.elasticsearch.* and global.opensearch.* trees were deprecated in the 8.9 chart and are removed in chart 15.x. Setting any key under them fails the render with a keyRemoved error that names the replacement. Map your values as follows (shown for Elasticsearch; the OpenSearch keys mirror them):

Removed keys
Removed keyReplacement
global.elasticsearch.enabledoptimize.database.elasticsearch.enabled (Optimize and the legacy Zeebe exporter) and/or orchestration.data.secondaryStorage.type: elasticsearch. The legacy Zeebe exporter is rendered automatically when Optimize is enabled in the same release; without Optimize, enable it with orchestration.exporters.zeebe.enabled: true.
global.elasticsearch.externaloptimize.database.elasticsearch.external.
global.elasticsearch.url.*optimize.database.elasticsearch.url.{protocol,host,port} and/or the full-URL string orchestration.data.secondaryStorage.elasticsearch.url.
global.elasticsearch.auth.*optimize.database.elasticsearch.auth.* and/or orchestration.data.secondaryStorage.elasticsearch.auth.*.
global.elasticsearch.tls.secret.*optimize.database.elasticsearch.tls.secret.* and/or orchestration.data.secondaryStorage.elasticsearch.tls.secret.*, or preferably global.tls.caBundle.secret with a PEM CA bundle. The component tls.secret.* keys still work but are deprecated in chart 15.x.
global.elasticsearch.tls.jks.secret.*Removed with the truststore password injection. Use global.tls.caBundle.secret (PEM), or pass -Djavax.net.ssl.trustStorePassword=... via the component's javaOpts. No secret-backed alternative is available: the chart renders JAVA_TOOL_OPTIONS before the component's env entries, so a $(VAR) reference to a Secret-sourced variable there does not expand.
global.elasticsearch.prefixoptimize.database.elasticsearch.prefix.
global.elasticsearch.clusterNameNo longer rendered; the application default is identical. If needed, set camunda.data.secondary-storage.elasticsearch.cluster-name via orchestration.extraConfiguration.
global.elasticsearch.disableExporterNo replacement needed (the key had no effect).
global.elasticsearch.tls.enabledNo replacement needed (the key had no effect; TLS activates from tls.secret.* or global.tls.caBundle being configured, not from a separate enabled flag).
global.opensearch.aws.enabledOpenSearch-only, no Elasticsearch equivalent: optimize.database.opensearch.aws.enabled and/or orchestration.data.secondaryStorage.opensearch.aws.enabled.

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

In chart 15.x (8.10), identity.serviceAccount.automountServiceAccountToken defaults to false, matching the other components. Management Identity does not call the Kubernetes API, so the application itself is not affected.

You are affected 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 added through identity.sidecars or identity.initContainers that calls the Kubernetes API.
  • Vault Agent Injector using the Kubernetes auth method with the default token.

Integrations that inject their own projected token, such as AWS IRSA, EKS Pod Identity, and Azure Workload Identity, are not affected.

The ServiceAccount is updated during helm upgrade, but running pods keep their token until they are recreated. The change takes effect on the next pod restart or rollout. To keep the previous behavior, set:

identity:
serviceAccount:
automountServiceAccountToken: true

Deprecated application configuration Helm keys​

In chart 15.x (8.10), Helm keys that acted as thin proxies for a single application setting are being deprecated in favor of the component's extraConfiguration. These keys continue to work in 8.10: setting one to a non-default value logs a [camunda][warning] DEPRECATION message on helm install or helm upgrade. They are planned for removal in a later major chart version, so migrating them while on 8.10 keeps your values file ready for that removal.

Deprecations are still being added

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

extraConfiguration lets each component own its native application configuration file. Its format (an ordered list of file entries, mounted and imported via spring.config.import for Spring Boot components) is unchanged from 8.9. For how it works per component, exclusion of non-Spring files with springImport: false, and how to find the exact application property for a given setting, see Application configuration and extraConfiguration. The most reliable way to find a target property name is to generate the component's default configuration file and locate the equivalent property there.

For the deprecated keys below, the chart resolves the effective value from your extraConfiguration (and, for the document store, suppresses the generated environment variables) so your migrated configuration takes effect in 8.10. You do not need to remove the deprecated key at the same time; if both are set, the extraConfiguration value takes precedence.

Each deprecated key moves to the listed component's extraConfiguration, except where noted.

Orchestration​

Move these keys to orchestration.extraConfiguration:

Deprecated orchestration keys
KeyNotes
orchestration.logLevelzeebe.log.level (broker log level).
orchestration.log4j2Move 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. It doesn't apply to the legacy Zeebe exporter, whose prefix is orchestration.exporters.zeebe.index.prefix.
orchestration.index.replicascamunda.data.secondary-storage.<elasticsearch|opensearch>.number-of-replicas.
orchestration.history.retention.enabledcamunda.data.secondary-storage.retention.enabled. It also enables the Operate and Tasklist archiver ILM settings.
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)
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.unprotectedApi. Cannot be true together with multi-tenancy checks. See Troubleshooting.
orchestration.security.authentication.oidc.usernameClaimcamunda.security.authentication.oidc.username-claim
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 replaces the audience list. See Troubleshooting.
orchestration.security.authentication.authenticationRefreshIntervalcamunda.security.authentication.oidc.authenticationRefreshInterval.
orchestration.security.authorizations.enabledcamunda.security.authorizations.enabled.
orchestration.security.initialization.mappingRulescamunda.security.initialization.mapping-rules.
orchestration.security.initialization.defaultRoles.<role>.mappingRulescamunda.security.initialization.default-roles.<role>.mappingrules. 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.multiTenancy.checksEnabled
orchestration.multitenancy.api.enabledcamunda.security.multiTenancy.apiEnabled
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.redirectUrlBase redirect URL that sets three OIDC properties: camunda.security.authentication.oidc.redirect-uri (<base>/sso-callback), camunda.operate.identity.redirectRootUrl (<base>/operate), and camunda.tasklist.identity.redirectRootUrl (<base>/tasklist). If you set only one, the login callback, Operate, and Tasklist use different hosts.
orchestration.upgrade.allowPreReleaseImagescamunda.system.upgrade.enable-version-check (inverted: allowPreReleaseImages: true maps to enable-version-check: false).

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 noted. Entries marked Native config use Optimize's own configuration property names rather than the camunda.* namespace; set them in optimize.extraConfiguration as well:

Deprecated optimize keys
KeyNotes
optimize.logLevel, optimize.upgradeLogLevel, optimize.esLogLevellogging.level.{"io.camunda.optimize","io.camunda.optimize.upgrade","org.elasticsearch"}.
optimize.profilesspring.profiles.active.
optimize.caches.cloudTenantAuthorizations.{maxSize,minFetchIntervalSeconds}camunda.optimize.caches.cloud-tenant-authorizations.{max-size,min-fetch-interval-seconds}.
optimize.partitionCountNative config zeebe.partitionCount.
optimize.database.{elasticsearch,opensearch}.prefixNative config zeebe.name.
optimize.multitenancy.enabledMove to global.multitenancy.enabled (not extraConfiguration). This is a platform-wide switch that requires Identity with an external database. See Logical Tenants.

Camunda Hub​

Move these legacy keys to camundaHub.restapi.extraConfiguration:

Deprecated keysNotes
webModeler.restapi.mail.{fromAddress,fromName,smtpHost,smtpUser,smtpPort,smtpTlsEnabled}camunda.hub.mail.* and spring.mail.*.
webModeler.restapi.logging.level.{"io.camunda.modeler","io.grpc"}logging.level.*.

Camunda Hub authentication settings require no change for this upgrade. Your existing settings continue to work, and are translated to their 8.10 equivalents at startup. They are deprecated, however, and are removed in 8.11, so migrate to their 8.10 equivalents before upgrading to 8.11. For the mapping, see authentication configuration.

Global​

Move each key to the consuming component's extraConfiguration:

Deprecated keyNotes
global.config.requestBodySizeThe relevant spring.servlet.multipart.*, server.tomcat.max-http-form-post-size, and message-size properties per component.
global.zeebeClusterNamezeebe.broker.cluster.clusterName on the orchestration component.
global.documentStore.type.{aws,gcp,inmemory}.storeIdThe unified camunda.document.* config (default-store-id plus the store definition) on each document-consuming component. See Troubleshooting.

Migrate extraConfiguration entries​

The extraConfiguration value format is unchanged from 8.9. If you already use extraConfiguration, no format change is required for this upgrade. For the mechanics, per-component behavior, and a worked example of moving settings into a configuration file, see Application configuration and extraConfiguration.

The following condensed example shows the shape of the migration for the orchestration component:

# Before (8.9, deprecated keys)
orchestration:
logLevel: debug
data:
snapshotPeriod: 10m
history:
retention:
enabled: true
minimumAge: 45d

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

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.

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 database migration from 8.9 to 8.10 is not backward compatible. Stop all Web Modeler and Console workloads, take a verified database backup, and complete the migration before restoring traffic. For background on how Hub performs the database migration, see how Camunda Hub upgrades between versions.

warning

Do not use helm upgrade --atomic for this upgrade. After the database migration starts, do not roll the Helm release back to 8.9 without first restoring the 8.9 database backup. An 8.9 application cannot start successfully or serve requests with a partially or fully migrated 8.10 database.

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.

Stop Web Modeler and Console workloads​

Upgrade the release to 8.10 in the quiesce phase:

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

Confirm both Web Modeler Deployments show zero desired and available replicas. Also confirm the 8.9 Console Deployment and pods have terminated:

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

Stop any external processes that write to the Hub database. Confirm no Hub writers remain before continuing.

Back up the Hub database​

Create a vendor-native backup of the Hub database after Hub is quiesced. This backup is the recovery point if 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.

Do not continue until you have confirmed the Hub database backup can be restored.

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 \
--wait \
--timeout 10m

Disabling the REST API liveness probe prevents Kubernetes from restarting the pod during a long-running migration. Wait for the single Hub REST API pod to become ready. The pod runs the database migration during startup but remains fenced from the Hub Service:

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

Review the REST API logs and validate the migrated Hub data before restoring traffic:

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

Look for an entry as follows:

[2026-09-11 15:05:06.501] [main] INFO
org.flywaydb.core.internal.command.DbMigrate - Successfully applied 33 migrations to schema "public", now at version v20260828 (execution time 00:00.380s)

Note that the number of migrations, the final version, and the execution time may vary depending on the exact versions you migrate between and your database setup.

If migration fails and you must return to 8.9:

  1. Set camundaHub.upgrade.phase back to quiesce and wait for both Hub Deployments to reach zero replicas, as described in Stop Web Modeler and Console workloads.
  2. Confirm all other processes that can write to the Hub database are stopped.
  3. Restore and verify the 8.9 Hub database backup.
  4. Roll back the Helm release to the intended 8.9 release revision.

Restore Hub traffic​

After validating 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 for both Hub workloads:

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 rely on the operator to follow this sequence. The chart does not yet prevent you from selecting normal before migration completes.

For a fresh 8.10 installation, leave camundaHub.upgrade.phase at its default value, normal. The quiesce and migrate phases apply only when upgrading an existing 8.9 Hub database.

Migrate document-store cloud credentials​

This migration applies only when a component relies on 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 warning appears when global.documentStore.activeStoreId is aws or gcp.

note

<component>.env supports Helm's tpl templating (for example, {{ .Release.Name }}); <component>.envFrom does not - it is rendered as plain YAML.

AWS - Static access key / secret key​

Connectors - used by the AWS SDK default credentials chain 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
- name: AWS_REGION
valueFrom:
secretKeyRef:
name: connectors-aws-credentials
key: region

Optimize - used to sign AWS OpenSearch requests when global.opensearch.aws.enabled (or optimize.database.opensearch.aws.enabled) is true:

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's credential resolution failures are caught and silently fall back to Basic authentication - verify the OpenSearch connection after migrating rather than relying on 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 can load both keys at once via envFrom instead, if the secret's data keys are already named AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and 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 using the eks.amazonaws.com/role-arn annotation.

For both IRSA and EKS Pod Identity, set AWS_REGION explicitly for Optimize and Camunda Hub. The AWS identity integrations provide credentials, not the region. Connectors doesn't need AWS_REGION because its element templates carry the region per task.

GCP​

Connectors:

The examples below use gcp-credentials as the Secret name and expect its data key to be named service-account.json. Replace the name with the Secret you use. If your 8.9 global.documentStore.type.gcp.credentialsKey used another key, map that key to service-account.json with secret.items, or update GOOGLE_APPLICATION_CREDENTIALS to the mounted filename.

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

Optimize:

optimize:
env:
- name: GOOGLE_APPLICATION_CREDENTIALS
value: /var/secrets/gcp/service-account.json
extraVolumeMounts:
- name: optimize-gcp-credentials
mountPath: /var/secrets/gcp
readOnly: true
extraVolumes:
- name: optimize-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 annotation-based equivalent of IRSA, on <component>.serviceAccount.annotations:

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

Azure​

No migration needed for these three components: global.documentStore.type.azure.* was never wired into connectors, optimize, or web-modeler-restapi in any chart version - only the document store feature itself (owned by orchestration) reads it.

Identity​

If you configured Aurora/RDS IAM authentication manually through identity.env, keep the datasource override and migrate its ambient AWS configuration. Supply static credentials and AWS_REGION through identity.env or identity.envFrom; for IRSA, annotate identity.serviceAccount, or create an EKS Pod Identity association. With either workload identity mode, set AWS_REGION only when the database is in a different region than the cluster.

Not affected​

  • Orchestration continues to own global.documentStore.type.* for the document store feature itself. No change is needed if that is all you use it for.

Monitor and validate the upgrade​

After triggering the Helm upgrade, monitor the rollout to ensure all pods return to a healthy state.

Watch pod rollout progress​

kubectl -n <NAMESPACE> get pods -w

You should see pods terminating and restarting with updated images.

Inspect logs (if required)​

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

Validate the upgrade​

  1. Confirm all pods are healthy and running 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. Review the helm upgrade output for any [camunda][warning] DEPRECATION messages. Each one names a key still to migrate before it is removed in a later major chart version.

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

Troubleshooting​

Upgrade failed due to missing secrets​

If your upgrade fails due to missing credentials, see Extract plaintext values and reference them as Kubernetes Secrets. For additional context, see Helm chart Bitnami legacy values file.

Upgrade failed with secondary storage validation error​

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

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

Alternatively, if you do not need secondary storage, set global.noSecondaryStorage: true.

Backwards-compatible audiences replace the audience list​

The deprecated orchestration.security.authentication.oidc.backwardsCompatibleAudiences appended its values to the default audiences, but its target, camunda.security.authentication.oidc.audiences, replaces the whole list. If you migrate it verbatim, the broker only accepts your extra audience and rejects tokens for the chart's default audiences (by default orchestration, orchestration-api, and web-modeler-api) with UNAUTHENTICATED: Expected a valid token. List the full default audience set alongside your backwards-compatible audience in audiences.

Initialization authorizations report "No permissionTypes provided"​

If the orchestration pod fails to start with IdentityInitializationException: Cannot initialize configured authorizations: No permissionTypes provided, the authorization entry uses the wrong field name. Under camunda.security.initialization.authorizations, the permission list field is permissions, not permissionTypes.

Custom document store ID​

A non-default global.documentStore.type.inmemory.storeId (or aws/gcp) cannot be used through the deprecated key alone: the default store ID is derived from global.documentStore.activeStoreId (the store type), never the custom store ID, so 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 each document-consuming component's extraConfiguration.

Multi-tenancy with an unprotected API​

camunda.security.multiTenancy.checksEnabled: true cannot be combined with camunda.security.authentication.unprotectedApi: true; the orchestration pod fails with Multi-tenancy is enabled ... but the API is unprotected. Protect the API when multi-tenancy is enabled.

Next steps​

This upgrade keeps your deployment in the chart's default combined topology: one Helm release running every enabled component. Nothing in the upgrade changes your release layout.

For a new production deployment, Camunda 8.10's baseline topology is instead one Hub release plus one release per Orchestration Cluster, with one Optimize release per Physical Tenant. See Camunda 8.10 deployment topology.

Adopting that topology on an existing deployment is a separate operation with its own data, storage, and rollback planning. Complete this version upgrade first, then see move from a combined release to the split topology.