Skip to main content

Overview

Temporal is an open-source (MIT) durable-execution platform: applications write workflows as ordinary code, and the Temporal server guarantees they run to completion, surviving process crashes, restarts, and long waits. This template deploys the Temporal server (one replica by default, or a cluster of up to five) with its gRPC frontend and HTTP API, plus the Temporal Web UI. The server is internal-only; the UI is internal-only too unless you open it to IP ranges you list. Closed workflows can optionally be archived to S3. By default the server is backed by the Postgres Highly Available template as a bundled subchart; a single-instance Postgres subchart is available for lighter installs. Database creation, schema migrations and the default namespace are handled automatically.
This template deploys into an existing GVC that you already have. It does not create one.

What Gets Created

In HA mode with postgresHA.backup.mode: wal-g, no cron workload is created; a wal-g-backup sidecar container runs inside RELEASE_NAME-postgres-ha instead.

Prerequisites

A database credentials secret must exist before you install. It is a dictionary secret holding username, password and database; the bundled PostgreSQL initializes with it and Temporal connects with it. Secrets are org-level, so no GVC flag is involved:
  • database must be temporal. The server reads its main store from the database named temporal, while PostgreSQL creates the one the secret names. With any other value both Temporal containers stop at boot and log CPLN_TEMPORAL_DATABASE_GUARD.
  • Set its name in the key of the database mode you use: postgresHA.config.credentialsSecretName (HA, the default) or postgres.config.credentialsSecretName (single-instance). Secret names are org-wide, so give each Temporal release its own secret.
  • PostgreSQL reads the secret only when its data is first initialized — see Rotating the Database Password.
If the secret does not exist at install time the deployment wedges silently. cpln logs returns zero lines — the containers never start, so there is nothing to log. The only place the missing secret is named is status.versions[].message:
Use get-deployments; plain cpln workload get has no versions key. Create the missing secret and the deployment recovers on its own after several minutes.
Optional database backups need a bucket and, for AWS or GCP, a Control Plane Cloud Account. Backups to MinIO or another S3-compatible endpoint additionally need a dictionary secret holding accessKey and secretKey, which must exist before you enable them. See Backing Up. Optional archival needs an S3 bucket, an AWS Cloud Account and a bucket-scoped IAM policy, set up before you set archival.enabled: true. See Archival Storage Setup.

Installation

Install with the name of the database credentials secret you created. Nothing else is required for a default install:
In single-instance mode set postgres.config.credentialsSecretName instead.

UI

Browse, install, and manage templates visually

CLI

Manage templates from your terminal

Terraform

Declare templates in your Terraform configurations

Pulumi

Declare templates in your Pulumi programs

Configuration

Temporal Server

  • image / adminTools.image — The Temporal server and the admin sidecar that runs alongside it in every replica. Both must carry the same tag, and the chart accepts only tags in the 1.30, 1.31 and 1.32 minors. Temporal upgrades one minor version at a time; see Upgrading from 1.x.
  • replicas — Every replica runs the full server, and together they form one Temporal cluster. See Scaling and Availability before changing it.
  • historyShards — Fixed when the cluster is first created. A later change has no effect: the server keeps the original count. 512 suits most deployments, so size it before installing.
  • namespaceRetention — How long closed workflow histories stay queryable in the default namespace, as a Go duration such as 72h or 168h. It is applied only when the namespace is first created; a later change does not alter an existing namespace.

Web UI

  • ui.enabled — Set false to remove the UI workload.
  • ui.allowedCIDRs — IP ranges that may open the UI in a browser on its canonical endpoint, such as your office or VPN egress address (203.0.113.10/32). Empty keeps the UI internal-only. IPv4 ranges must be /8 or narrower and IPv6 ranges /32 or narrower; the chart refuses broader ranges, including the whole internet. A change takes up to a few minutes to apply. Only the UI is opened; the server stays internal-only.
The Temporal Web UI has no login: anyone who can reach it can view and act on every workflow. List only addresses you trust in ui.allowedCIDRs.

Access

The server is never reachable from outside Control Plane: workers and clients run as workloads in your org. The UI is internal-only too unless you list IP ranges in ui.allowedCIDRs. internalAccess.type sets the internal firewall scope for the server and the UI: Changing internalAccess restarts every server replica, and a change can take a few minutes to take effect. Re-test rather than trusting the first response.

Archival

Archival copies closed workflow histories and visibility records to S3, so they stay readable after the namespace’s retention deletes them. This template supports S3 only, reached through the server’s workload identity with no stored keys, and archival needs Temporal server 1.31 or later. Complete the Archival Storage Setup below before turning it on.
  • archival.enabled — Declares the S3 archiver on the server and binds the server identity to your AWS cloud account and IAM policy. The chart refuses it on a 1.30 image; when upgrading from 1.x, turn it on after the step to 1.31.
  • archival.defaultNamespace — Whether the default namespace archives. With archival on, default archives to s3://BUCKET/PREFIX/history and s3://BUCKET/PREFIX/visibility, including on an existing install.
  • archival.s3.* — The bucket, its region, the folder in the bucket, the cloud account and the IAM policy from the setup steps.
To stop archiving, set archival.defaultNamespace: false and keep archival.enabled: true. Never set archival.enabled: false once archival has been used: the default namespace can then no longer be updated, archived workflows become unreadable, and the server keeps retrying to archive every closed workflow.
A workflow appears in the archive a few minutes after it closes. Read archived workflows back from the admin container:
While archival.defaultNamespace is false, temporal workflow list --archived returns Namespace is not configured for visibility archival., but temporal workflow show with -r RUN_ID still reads archived histories.
  • Temporal never changes a namespace’s archival target once it is set, so a later change to bucket or prefix applies only to namespaces that do not archive yet.
  • Other namespaces can archive to the same bucket: create them with temporal operator namespace create -n NAMESPACE --history-archival-state enabled --history-uri s3://BUCKET/PREFIX/history --visibility-archival-state enabled --visibility-uri s3://BUCKET/PREFIX/visibility.
  • The server identity keeps its AWS binding until the release is uninstalled.

Archival Storage Setup

Archival reaches the bucket through the server’s workload identity, so no access keys are stored.
1

Create an S3 bucket

Create an S3 bucket. Set archival.s3.bucket to its bare name (no s3://) and archival.s3.region to its region.
2

Set up a Cloud Account

If you do not have one, create a Cloud Account for your AWS account. Set archival.s3.cloudAccountName to its name.
3

Create a bucket-scoped IAM policy

Create an AWS IAM policy with the JSON below. Replace YOUR_BUCKET, and YOUR_PREFIX with the value of archival.s3.prefix. The server lists the bucket and writes and reads archives under the prefix; it never deletes from it.
Set archival.s3.policyName to the policy’s name.

PostgreSQL

Exactly one of postgresHA and postgres must be enabled; the chart refuses to render otherwise.

Highly Available PostgreSQL

  • postgresHA.config.credentialsSecretName — Name of the prerequisite database credentials secret the HA cluster and Temporal read (see Prerequisites). Secret names are organization-wide, so give each Temporal release its own.
  • postgresHA.replicas / postgresHA.volumeset.capacity — PostgreSQL replica count and volume size per replica. The remaining cluster settings take the defaults of the Postgres Highly Available template; the HAProxy leader endpoint must stay enabled because it is the address Temporal connects to.
  • postgresHA.backup.* — Optional backups of both Temporal databases, as scheduled logical dumps or continuous WAL-G archiving. Keep resources.memory at 512Mi or more for WAL-G. See Backing Up.

Single-Instance PostgreSQL

Enable this block and disable postgresHA for a lighter non-HA deployment.
  • postgres.config.credentialsSecretName — Name of the prerequisite credentials secret in single-instance mode (the HA counterpart is postgresHA.config.credentialsSecretName). Its database key must be temporal.
The credentials are applied once, when the database volume is first initialized. Changing the secret on an existing release does not change the password PostgreSQL enforces, so the server can no longer connect. To rotate, follow Rotating the Database Password.

Connecting

The server exposes no public endpoint: everything except the browser UI is reachable only from workloads inside the internalAccess scope. The Web UI is reachable in a browser from the IP ranges you list in ui.allowedCIDRs. Confirm the server is serving by listing workflows with the temporal CLI in the admin sidecar. On a fresh install the list is empty and the command exits without an error:
To use the Web UI in a browser, list your address in ui.allowedCIDRs, upgrade the release, and open the UI’s canonical endpoint:
A change to ui.allowedCIDRs takes up to a few minutes to apply; until then the endpoint answers 403. For a quick check without opening the UI, tunnel to it instead and request http://localhost:8080/healthz:
A browser through cpln port-forward can stop loading pages after some navigation, so use ui.allowedCIDRs for browser use.

First Run

Temporal has no setup wizard. A fresh install already has a default namespace, so the first run is a worker and a workflow.
1

Check the namespace in the Web UI

Open the Web UI as described above. The default namespace is already registered, with the retention you set in namespaceRetention.
2

Run a worker

Workers run as their own workloads inside the internalAccess scope and connect to the gRPC frontend by its full hostname. A minimal Python worker with one workflow and one activity:
Python workers must guard their entrypoint with if __name__ == "__main__":. The Temporal Python SDK’s workflow sandbox re-imports the worker module, and an unguarded module-level main() crashes the worker.
3

Start a workflow

Start a workflow on the worker’s task queue from the Web UI’s Start Workflow form, or with the temporal CLI in the admin sidecar:
The run appears in the Web UI under Workflows.

Nexus and Worker Deployments

These need no template configuration:
  • Nexus works with endpoints that target a namespace and task queue in this Temporal cluster; create them with temporal operator nexus endpoint create or the UI’s Nexus page. Endpoints that target an external URL are not supported.
  • Worker Deployments (worker versioning, pinned and auto-upgrade workflows) work. The UI’s Workers Instances tab relies on worker heartbeats, which need Python SDK 1.20 or later.

Operations

Backing Up

Database backups are optional and disabled by default. They cover both Temporal databases, temporal (workflow histories, task queues, timers) and temporal_visibility. Enable them with postgresHA.backup.enabled or postgres.backup.enabled, matching your database mode, and complete the storage setup for your provider before enabling. The keys below are written as backup.*; set them inside the enabled database block. In HA mode, postgresHA.backup.mode selects logical (a scheduled pg_dumpall from the RELEASE_NAME-postgres-ha-backup cron workload) or wal-g (continuous WAL archiving from a wal-g-backup sidecar inside RELEASE_NAME-postgres-ha, with a base backup every walg.intervalSeconds). Single-instance mode takes scheduled logical dumps only.
1

Create a bucket

Create an S3 bucket. Set backup.aws.bucket and backup.aws.region to match.
2

Set up a Cloud Account

If you do not have one, create a Cloud Account for your AWS account. Set backup.aws.cloudAccountName to its name.
3

Create a bucket-scoped IAM policy

Create an AWS IAM policy with the JSON below (replace YOUR_BUCKET), then set backup.aws.policyName to the policy’s name. The template attaches that policy to the backup identity and nothing else, so the bucket in your policy is the only storage the backup can reach:
To take a logical backup on demand, for example before an upgrade, start the cron job once and check that its run reports Successful:
In single-instance mode the cron workload is RELEASE_NAME-postgres-backup. With WAL-G, the leader’s wal-g-backup container logs Backup complete after each base backup.
Volume set snapshots are not a supported restore path for the HA database. Restoring them onto a running Patroni cluster does not bring the database back to its earlier state. Use the backups above.

Restoring a Backup

This restore path has not been exercised against a Temporal install. It is derived from the backup image (a pg_dumpall of the whole server, gzip-compressed) and from the restore procedure of the bundled database templates. Rehearse it on a throwaway release before you depend on it.
A logical backup is a full-server dump (pg_dumpall), so one file holds both Temporal databases and the temporal role. Restore into a database Temporal is not writing to: the dump recreates temporal and temporal_visibility, so the cleanest target is a database from which both have been dropped, with the Temporal server not running against it. Then run the pipeline documented by the bundled database template from a client with access to the bucket, using the username and password from cpln secret reveal DB_CREDENTIALS_SECRET_NAME -o yaml and the matching host: RELEASE_NAME-postgres-ha-proxy.GVC_NAME.cpln.local in HA mode, RELEASE_NAME-postgres.GVC_NAME.cpln.local in single mode.
For GCS replace the first line of the pipeline with gsutil cp "gs://BUCKET_NAME/PREFIX/BACKUP_FILE.sql.gz" -; for MinIO export AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, run aws configure set default.s3.addressing_style path, and add --endpoint-url "http://MINIO_ENDPOINT:9000" to the aws s3 cp. The WAL-G point-in-time procedure for HA mode is documented on the Postgres Highly Available page and carries the same caveat above.

Upgrading from 1.0.x

Apply every subsection from your version onward, in order, ending with Upgrading from 1.x. Each removed key is rejected at render, so an upgrade that still carries one fails before anything is applied and the running release is left untouched. Version 1.1.0 moved the bundled single-instance database to the postgres 3.4.1 template, which no longer takes credentials or MinIO keys as values: Carrying an old credentials key forward fails with the bundled Postgres template’s message, which begins config.username was REMOVED in postgres 3.4.0 and tells you to create a dictionary secret — that is correct here too. Use the username and password your database was initialized with, not new ones.
Template version 1.0.0 did not compact the etcd cluster inside the bundled HA database, so its backend grew with time alone and eventually went read-only, taking PostgreSQL failover with it. Only HA-mode installs are affected. Upgrading to 1.0.1 or later turns compaction on, which stops further growth but cannot shrink a backend that has already grown; a cluster that has already raised a NOSPACE alarm needs operator recovery rather than an upgrade. The mechanism and the inspection commands are on the Postgres Highly Available page.

Upgrading from 1.1.0

Version 1.2.0 moved the bundled HA database to postgres-highly-available 2.5.0, which removed the postgresHA.postgres block. The HA cluster now reads the database credentials secret under Prerequisites (database must be temporal), named by postgresHA.config.credentialsSecretName.
Use the credentials your cluster already has. The HA cluster was initialized with the postgresHA.postgres.* values you installed with, and PostgreSQL still enforces them. Put that username and password into the credentials secret before upgrading. Putting new values there does not change the database, and Temporal can no longer authenticate.
An upgrade that still carries the postgresHA.postgres block fails with the HA template’s message, which begins postgres-highly-available: the `postgres` block was REMOVED in 2.5.0 and tells you to create a dictionary secret — that is correct here: delete the block and set postgresHA.config.credentialsSecretName to the secret’s name.

Upgrading from 1.2.x

  • From 1.2.0, HA MinIO backups only: version 1.2.1 replaced postgresHA.backup.minio.accessKey and postgresHA.backup.minio.secretKey with postgresHA.backup.minio.credentialsSecretName, a dictionary secret you create holding accessKey and secretKey; see Backing Up. The HA and single-instance paths now use the same shape.
  • From 1.2.0 or 1.2.1: version 1.3.0 renamed the resource limits so the ceiling is no longer ambiguous next to the floor. Rename these keys in your values; an upgrade carrying an old name is refused at render with resources.cpu was RENAMED to resources.maxCpu (or the matching message for the other three):
The values themselves are unchanged (1000m / 2Gi for the server, 500m / 512Mi for the UI), so a release on the defaults upgrades with no resource change.

Upgrading from 1.x

Temporal supports upgrading one minor version at a time. Every 1.x release of this template runs Temporal server 1.29.7, and version 2.0.0 defaults to 1.32.1, so the move takes three upgrades: 1.30.8, then 1.31.4, then the chart defaults. A direct upgrade with the defaults is refused before the database is touched. Run all three steps at replicas: 1, and raise replicas only after the last one.
1

Back up first

A migrated schema cannot be rolled back. If backups are not on yet, enable postgresHA.backup (HA) or postgres.backup (single-instance) on your current release as described in Backing Up, then take a backup now and confirm it succeeded. With logical backups:
In single-instance mode the cron workload is RELEASE_NAME-postgres-backup. With WAL-G, wait for Backup complete in the leader’s wal-g-backup container logs. Volume set snapshots are not a supported recovery path for the HA database.
2

Upgrade to 2.0.0 on Temporal 1.30

Upgrade with your existing values file and both images pinned to 1.30.8:
If your values file sets image: temporalio/auto-setup:…, delete that line first: version 2.0.0 refuses the auto-setup image.
On the HA database, plan this first step in a maintenance window. It also updates the bundled PostgreSQL cluster, which restarts every member and fails the leader over, leaving Temporal without its database for about 2.5 minutes after the schema step has finished. Workflows resume afterwards. The later steps, and the single-instance database, have no such outage.
3

Wait

Wait until the server is ready, then about 10 more minutes.
4

Upgrade to Temporal 1.31

Run the same command with 1.31.4 in both --set values, then wait again.
5

Upgrade to Temporal 1.32

Run the same command without the two --set values; the chart defaults are 1.32.1.
6

Upgrade to 2.1.0

Each step migrates the schema before the new server starts. A step that skips a minor version is refused before the database is touched: the new replica never becomes ready while the old one keeps serving, and its admin container logs CPLN_TEMPORAL_SKIP_GUARD with the tag to use next. Set that tag and upgrade again. Also in this version:
  • AWS backups: the HA backup no longer attaches AWS’s ReadOnlyAccess policy. Update your bucket-scoped IAM policy to the full action list under Backing Up before upgrading.
  • Temporal 1.32 visibility queries are stricter: a list filter that compares a search attribute with the wrong type, or an empty Text filter, now returns an error instead of results.
  • New optional features: archival to S3, which needs Temporal 1.31 or later, so turn it on after the step to 1.31; and browser access to the Web UI from listed IP ranges with ui.allowedCIDRs (see Web UI).

Upgrading from 2.0.0

Version 2.1.0 removed postgres.credentials: the database credentials are now a prerequisite secret, the same one the database templates require on their own. Carrying the old key forward fails the render. 2.0.0 created the database secret itself, so this upgrade deletes it. Before upgrading, create a secret under a new name holding the values your database was initialized with — not new ones, or Temporal loses its database connection. database stays temporal:
SECRET_NAME is the credentialsSecretName of the mode you use in the 2.0.0 release (default my-temporal-db-credentials). Then upgrade with postgresHA.config.credentialsSecretName (HA mode) or postgres.config.credentialsSecretName (single-instance mode) set to the new name, and postgres.credentials removed. Your current values are also in postgres.credentials of the 2.0.0 release. The upgrade restarts the bundled PostgreSQL too (it now reads the new secret), so Temporal can briefly lose its database; it reconnects by itself. While access to the new secret propagates, the new version of a workload can wait in get-deployments reporting that it is not allowed to reveal the secret; the previous version keeps serving meanwhile, and it clears by itself.

Upgrading from 2.1.0 or earlier

2.1.1 moves the HA database (postgresHA) to controlplanecorporation/patroni-postgres:0.8, which carries pgvector 0.8.7 (CVE-2026-103484). The fix takes effect when the upgrade restarts the Patroni members; existing data needs nothing. Nothing limits that rollout, so expect a brief interruption of writes while the leader changes. Temporal itself restarts without a gap, but its API is briefly unavailable while the database leader changes; running workflows and schedules continue. Upgrade in a quiet window. If you pinned postgresHA.image in your values, set it to the 0.8 tag: tags 0.1 to 0.7 are refused at render. Temporal does not use the vector extension; if you created it yourself in a database, \dx keeps reporting the old version until you run ALTER EXTENSION vector UPDATE; there, which only updates that record. Single-instance mode (postgres) is unchanged.

Rotating the Database Password

A running workload keeps the credential values it started with, and PostgreSQL reads the secret only when its data is first initialized, so editing the secret alone does not change the database password. Change one key and keep the others with export, edit, apply — keep database at temporal:
Single-instance mode takes three steps in order:
  1. Change it in the database: ALTER ROLE DB_USERNAME PASSWORD 'NEW_PASSWORD'; (connected as that user, from inside the GVC).
  2. Update the secret as above.
  3. Right away, redeploy Temporal, and wait until get-deployments shows a higher version number, alone and ready (right after the command the status may not show the restart yet, and ready: true alone can still describe the old replica). Do not redeploy the database: PostgreSQL reads the secret only when it is first initialized, so restarting it only adds downtime.
Temporal keeps serving on the database connections it already has open. Do step 3 right away: if those connections drop before Temporal restarts, it cannot open new ones. HA mode (the default) needs its own order. The replication role repl shares the password, and a member that restarts with the old password can be promoted to leader, which splits the cluster. Move the leader to member -0 first, so it restarts last, after every other member already has the new password. pgx runs a command in one member (LOCATION is your GVC’s location, DB_USERNAME the secret’s username):
Then force-redeploy RELEASE_NAME-temporal, which keeps the old password until it restarts. The app cannot open new database connections from the ALTER ROLE until its own redeploy finishes, so rotate in a quiet window. If a member stays starting, or running without streaming, re-copy it from the leader. This copies the whole database, so it costs network traffic in proportion to its size:

Scaling and Availability

  • replicas sets the server count, from 1 to 5. Every replica runs the full server and they form one Temporal cluster. 3 survives the loss of a replica with capacity to spare; 1 is fine when a short gap per upgrade or restart is acceptable.
  • Add replicas for availability, not throughput. Each replica’s database connection pools shrink as replicas are added, so that the whole cluster stays within the bundled database’s connection limit.
  • Changing replicas restarts every server replica, not just an added or removed one, because the per-replica pool sizes change. Changing internalAccess also restarts every server replica. Members join or drain and work rebalances on its own.
  • Change replicas under light load. While replicas with the old and the new pool sizes run side by side, the total connection count can briefly exceed the database’s limit.
  • Rolling restarts with more than one replica take several minutes. Replicas are replaced one at a time. A newly started replica may restart its worker service a few times in its first minutes before settling; clients are not affected.
  • Losing a replica: the remaining replicas take over its workflows and the platform replaces it. Timers fire on time and nothing is lost; clients may see a few timed-out calls right after the loss.
  • Workers scale independently. Run as many worker workloads and replicas as your task queues need.
  • Database availability is the HA cluster’s job. In the default postgresHA mode a PostgreSQL leader failure is handled by Patroni and the HAProxy endpoint keeps the same address. In postgres mode there is no failover.
  • Durability is in the database, not the server. The server workload has no volume. cpln helm uninstall deletes the database volume sets, taking every workflow history with it.

Troubleshooting

Symptom: A new RELEASE_NAME-temporal replica never becomes ready after an install or upgrade.Cause: The admin sidecar gates the server on the schema. Read its logs:
CPLN_TEMPORAL_SKIP_GUARD means the image skips a minor version, and the message names the tag to use next. another replica is migrating the schema is normal during an upgrade with several replicas.Fix: For a skipped minor, upgrade again with the named tag on both image and adminTools.image, as in Upgrading from 1.x. The old replica keeps serving until then.
Symptom: helm upgrade stops at render with temporal: image "temporalio/auto-setup:…" is the retired auto-setup image.Cause: Your values file still sets the 1.x server image.Fix: Delete the image line and follow Upgrading from 1.x.
Symptom: Render fails with temporal: image (…) and adminTools.image (…) must carry the same tag.Cause: Only one of the two images was changed.Fix: Set both image and adminTools.image to the same tag.
Symptom: Render fails with temporal: image tag "…" is not supported.Cause: The chart runs only Temporal server 1.30.x, 1.31.x or 1.32.x, given as a full tag.Fix: Use a full tag in one of those minors, such as 1.32.1.
Symptom: Render fails with temporal: replicas must be a whole number from 1 to 5.Cause: replicas is outside the supported range.Fix: Set replicas between 1 and 5.
Symptom: helm install or helm upgrade stops at render with temporal: enable exactly one database.Cause: Both database blocks are enabled, or neither is.Fix: Set exactly one of postgresHA.enabled and postgres.enabled to true. Switching an existing release between modes is a new database, not a migration; the data stays on the old mode’s volume set.
Symptom: The server never becomes ready, and its admin container logs CPLN_TEMPORAL_DATABASE_GUARD.Cause: The database credentials secret’s database key is not temporal. The server reads its main store as the literal database temporal.Fix: Set database to temporal in the secret, then force a redeployment of RELEASE_NAME-temporal. The database PostgreSQL created under the wrong name is unused and can be dropped.
Symptom: helm upgrade stops at render with temporal: postgres.credentials was REMOVED in 2.1.0.Cause: Your values still carry the 2.0.0 postgres.credentials block.Fix: Follow Upgrading from 2.0.0.
Symptom: helm upgrade stops at render with temporal: resources.cpu was RENAMED to resources.maxCpu (or the same message for resources.memory, ui.resources.cpu, ui.resources.memory).Cause: Your values file predates template version 1.3.0.Fix: Rename the keys as listed in Upgrading from 1.2.x.
Symptom: helm upgrade stops at render with a message beginning postgres-highly-available: the `postgres` block was REMOVED in 2.5.0.Cause: Your values still carry postgresHA.postgres.username, postgresHA.postgres.password or postgresHA.postgres.database from template version 1.1.0 or earlier.Fix: Delete the postgresHA.postgres block and put the same username and password into the database credentials secret. See Upgrading from 1.1.0.
Symptom: helm upgrade stops at render with config.username was REMOVED in postgres 3.4.0 (or the same for config.password / config.database).Cause: Your single-instance values still use postgres.config.username, postgres.config.password or postgres.config.database from template version 1.0.x.Fix: Put the three values into the database credentials secret. See Upgrading from 1.0.x.
Symptom: Render fails with temporal: archival needs Temporal server 1.31 or later, and this release runs 1.30.x.Cause: archival.enabled is true on a 1.30 image, typically during the first step of Upgrading from 1.x.Fix: Keep archival off until the release runs 1.31 or later, then turn it on.
Symptom: Render fails with ui.allowedCIDRs entry "…" is too broad for a UI with no login, … opens the Web UI to the whole internet, … is not an IP range, or temporal: ui.allowedCIDRs is set but ui.enabled is false. The list opens the Web UI workload, which is not deployed; turn the UI on or empty the list.Cause: The UI has no login, so the chart accepts only IPv4 ranges of /8 or narrower and IPv6 ranges of /32 or narrower, written as an address with a prefix length.Fix: List specific ranges, such as your office or VPN egress address with /32. If the UI is turned off, turn it on or empty the list.
Symptom: After an upgrade that set archival.enabled: false, updates of the default namespace fail with unable to find archiver config for the given scheme, and temporal workflow list --archived no longer returns archived workflows.Cause: The namespace still points at its S3 archive, and the server no longer declares the S3 archiver.Fix: Upgrade with archival.enabled: true again. To stop archiving, set archival.defaultNamespace: false instead.
Symptom: After an upgrade that changed historyShards, the cluster still reports its original shard count.Cause: The shard count is fixed when the cluster is first created; the server keeps the original value and ignores the new one.Fix: None is needed for a running cluster. A different shard count means a new release with a fresh database.
Symptom: A worker or client fails to resolve or reach the server.Cause: Either the worker uses the short workload name, which does not resolve, or it runs outside the internalAccess scope.Fix: Connect to RELEASE_NAME-temporal.GVC_NAME.cpln.local:7233 and make sure the worker’s workload is covered by internalAccess.type (or listed in internalAccess.workloads for workload-list). After changing the scope, allow a few minutes before re-testing.
Symptom: With MinIO backups enabled, RELEASE_NAME-postgres-ha-backup (or RELEASE_NAME-postgres-backup, or in wal-g mode RELEASE_NAME-postgres-ha itself) never becomes ready and cpln logs returns zero lines.Cause: The secret named by backup.minio.credentialsSecretName did not exist when the workload was applied.Fix: Create it as shown in Backing Up, then read status.versions[].message with cpln workload get-deployments WORKLOAD_NAME --gvc GVC_NAME -o yaml to confirm the reference resolves, or force a redeployment of the affected workload.
Symptom: A single-file Python worker crashes immediately with an error from inside the Temporal workflow sandbox.Cause: The module calls main() at import time. The SDK’s sandbox re-imports the worker module, re-running it.Fix: Guard the entrypoint with if __name__ == "__main__": as in the First Run sample.

Important Notes

  • Create the database credentials secret before installing, with database set to temporal. A missing secret wedges the deployment with zero log lines; status.versions[].message in cpln workload get-deployments RELEASE_NAME-temporal --gvc GVC_NAME -o yaml names it.
  • Editing the credentials secret does not change the database password — run ALTER ROLE first, then force-redeploy Temporal; in HA mode move the leader first (Rotating the Database Password).
  • Upgrade Temporal one minor version at a time, and back up through the database backup first. A skipped minor is refused; see Upgrading from 1.x.
  • historyShards is fixed at first install. A later change is ignored, so size it before installing.
  • The Web UI has no login. List only addresses you trust in ui.allowedCIDRs; ranges broader than /8 (IPv4) or /32 (IPv6) are refused, and a change takes up to a few minutes to apply.
  • To stop archiving, set archival.defaultNamespace: false. Never set archival.enabled: false once archival has been used.
  • Use the full .cpln.local hostname in every worker and client; short workload names do not resolve.
  • Give each release its own database credentials secret. Secret names are organization-wide, so two releases pointed at one secret share a password.
  • Keep the GVC to one location. Each location would run its own servers against its own database.
  • Uninstall deletes the database volume sets, taking every workflow history with it. Enable backups if the data matters.

External References

Temporal Documentation

Official Temporal documentation

Upgrading the Temporal Server

Upgrading a self-hosted Temporal Service one minor version at a time

SDKs

Writing workflows, activities, and workers in every supported language

Namespaces

Namespaces and workflow-history retention

Web UI Reference

The Temporal Web UI reference

Temporal Template

View the source files, default values, and chart definition