Upgrading Corteza

This guide helps you upgrade your Corteza to the newest version in no time!

While there are internal safeguards in place that can prevent data loss or other kinds of disasters, make sure you backup your database before you upgrade. Refer to devops guide on backup procedure for details.

If you are upgrading multiple versions at the same time; for example from 2019.12 to 2020.9; you should follow all the upgrade guides between the two versions.

Especially before any major version upgrade, it is recommended that before upgrading your production you either:
  • upgrade your staging environment, or

  • deploy a temporary environment with a copy of the production database and perform a test upgrade there.

Steps to upgrade Corteza when deployed with docker-compose:
  1. changing image versions in your docker-compose.yaml (or .env) file,

  2. pull new images from docker hub with docker-compose pull,

  3. recreate containers with docker-compose up -d.

If you are also taking over a docker-compose.yaml change that adds a volume to a service which previously had none, that service starts against an empty directory.

For the db service this means the database initialises a new, empty cluster on the next docker-compose up -d, while your existing data remains in the writable layer of the old container. Dump your database before recreating the containers and restore it afterwards.

Refer to devops guide on backup procedure for details.

Upgrading to 2026.9

The database schema is upgraded automatically when the server starts. A few changes need your attention before or after the upgrade; see the 2026.9 changelog for the full list of important upgrade notes.

Before the Upgrade

Back up your database before you upgrade. Security fixes in 2026.9 are not backported to 2024.9; upgrade to receive them.

Pin the image version

The latest Docker image tag now follows the newest stable release. Installations that run cortezaproject/corteza:latest move to 2026.9 on their next pull. Set the version explicitly in your .env (for example VERSION=2026.9, or VERSION=2024.9 to stay on the previous release) so you choose when to upgrade.

Set a JWT secret

When AUTH_JWT_SECRET is not set, the server derives it from DB_DSN and the HOSTNAME of the container. A new image means a new container with a new hostname, so every user is logged out after the upgrade. Set AUTH_JWT_SECRET to a long random value to keep sessions across upgrades and container restarts.

Check redirect URIs of auth clients

Auth clients without redirect URIs only accept redirects to the address of the server (AUTH_BASE_URL) and the webapp domain (DOMAIN_WEBAPP), and redirect URIs need to match scheme, host and port exactly. If web applications are served from another address, list it in AUTH_DEFAULT_REDIRECT_URIS or set redirect URIs on the auth client, otherwise logging in fails.

Review new options

HTTP_CLIENT_RESTRICTED_NETWORKS

Workflow HTTP and OAuth2 requests, the API Gateway proxy and remote resources inlined into templates can no longer reach link-local addresses, such as cloud metadata endpoints. Set it to private to also block private networks, or to none to lift the restriction.

SCIM_SECRET

SCIM endpoints are only available when the secret is set, also in development mode.

HTTP_CORS_ALLOWED_ORIGINS

Restricts which origins may make cross-origin requests; the default allows all, as before.

Building from source

The server needs Go 1.25 to build; web applications still build with Node 22.

After the Upgrade

Permissions

Several endpoints now require permissions they did not check before; see the important upgrade notes in the changelog. Most likely to need attention:

  • Corredor scripts that send email need the new Send email notifications permission on Compose. Fresh installations grant it to administrators; on existing installations grant it to the roles whose scripts send email.

  • Users can no longer change their own email, username, user group, kind or labels. Workflows that change these on the triggering user must run as a user with permission to update users.

  • Contextual role expressions can only use user.email (once confirmed) and user.labels; rewrite expressions that use user.name, user.handle or user.username.

  • Making a workflow run as another user, or changing a workflow that does, requires the impersonate permission on that user.

Workflow triggers

Triggers with an invalid interval, timestamp or constraint are now refused when a workflow is saved. If saving an existing workflow fails, the editor shows which trigger to fix.

Modules stored in their own table

Record creation fails with a NOT NULL violation on the values column when a module is stored in its own table and every field has its own column. New tables are created with a nullable values column; drop the constraint on tables created before the upgrade. Replace <table> with the table name of the module.

PostgreSQL
ALTER TABLE <table> ALTER COLUMN "values" DROP NOT NULL;
MySQL
ALTER TABLE <table> MODIFY `values` JSON NULL;
SQL Server
ALTER TABLE <table> ALTER COLUMN [values] VARCHAR(MAX) NULL;

Non-Latin text on SQL Server

Text and enum columns are now created as NVARCHAR on SQL Server, so non-Latin text is no longer stored as question marks. Columns created before the upgrade keep their VARCHAR type; change the text columns that must hold such text, for example:

ALTER TABLE <table> ALTER COLUMN <column> NVARCHAR(MAX) NULL;

JSON columns, such as the record values and the meta, config and label value columns, must stay VARCHAR(MAX). Corteza writes JSON as bytes, which SQL Server reads as UTF-16 when it stores them in an NVARCHAR column, so the JSON can no longer be read. If such a column was changed to NVARCHAR, change it back to VARCHAR(MAX); values written while it was NVARCHAR are not recoverable.

Non-Latin text inside JSON, such as record values of modules that keep their values in the values column, needs a database with a UTF-8 collation (SQL Server 2019 and later, for example Latin1_General_100_CI_AS_SC_UTF8); with other collations it is stored garbled.

Upgrading to 2024.9.6

The newly added user groups requires database schema modifications that may not be backwards compatible. The role_members table receives a new rel_resource column which is generated based on the rel_user column. After the upgrade, you need to either delete the rel_user column or drop the requirement the rel_user column is populated.

Before the Upgrade

Since the database schema will be modified, we recommend you create a backup just in case.

Run the following commands based on your database:

MySQL

ALTER TABLE role_members
    ADD COLUMN rel_resource TEXT;

ALTER TABLE role_members
    DROP PRIMARY KEY;

ALTER TABLE role_members
    ADD PRIMARY KEY (rel_resource, rel_role);

ALTER TABLE role_members
    MODIFY rel_user BIGINT UNSIGNED NULL;

PostgreSQL

ALTER TABLE role_members
    ADD COLUMN rel_resource text;

ALTER TABLE role_members
    DROP CONSTRAINT role_members_pkey;

ALTER TABLE role_members
    ADD CONSTRAINT role_members_pkey
        PRIMARY KEY (rel_resource, rel_role);

ALTER TABLE role_members
    ALTER COLUMN rel_user DROP NOT NULL;

SQL Server

ALTER TABLE role_members
    ADD rel_resource NVARCHAR(MAX) NULL;

ALTER TABLE role_members
    DROP CONSTRAINT role_members_pkey;

ALTER TABLE role_members
    ADD CONSTRAINT role_members_pkey
        PRIMARY KEY (rel_resource, rel_role);

ALTER TABLE role_members
    ALTER COLUMN rel_user BIGINT NULL;

After the Upgrade

If you’ll no longer require the column, you can safely delete it.

ALTER TABLE role_members DROP COLUMN rel_user;