# Breaking Changes

This page lists changes that require attention when updating an existing UDiTH
Portal installation. Changes are grouped by the release that introduced them; when
skipping releases, work through every section between the installed version and
the target version.

Database schema changes are applied automatically and are not listed here.

## 2026.4.0

### Changed default values

These defaults changed. An installation that sets the value explicitly is not
affected; an installation that relies on the default is.

| Setting                                | Old default | New default | Effect                                                                                     |
| -------------------------------------- | ----------- | ----------- | ------------------------------------------------------------------------------------------ |
| `TusSettings:TusEnabled`               | `false`     | `true`      | Resumable (chunked) uploads are enabled unless switched off                                  |
| `AccountRefreshInterval`               | *unset*     | `600000`    | Keycloak accounts are now synchronised every 10 minutes; set `0` to synchronise only at startup |
| `ModelHosting:ZipArchiveRemoveDuration`| `5000`      | `30000`     | Unused ZIP handlers are released less aggressively                                           |

### Docker: new image variants

The Portal image is now also published as `ubuntu` and `ubuntu-chiseled`, based
on Ubuntu 26.04 LTS. The existing `noble` and `noble-chiseled` variants (Ubuntu
24.04) still work but are considered legacy and will be removed with release
2027.0. See
[Setup Portal Linux](/UDiTH%20Portal/Setup%20Portal%20Linux) for the full list
and the matching volume permissions.

### Log forwarding to OpenTelemetry moved

Forwarding log output to an OTLP endpoint no longer requires a Serilog sink
entry. Setting `OpenTelemetry:Endpoint` now enables it. An existing
`Serilog:WriteTo:<n>:Name=OpenTelemetry` entry keeps working, but combined with
`OpenTelemetry:Endpoint` it causes log records to be sent twice. Remove one of
the two.

### Renamed metrics

Metric names now use dot-separated segments throughout, and counters and gauges
end in `.count`. Unit codes follow the OpenTelemetry convention. Existing
dashboards and alerts that use an old name return no data.

| Old name                                          | New name                                                 |
| ------------------------------------------------- | -------------------------------------------------------- |
| `portal.cmr.files.requested`                      | `portal.cmr.files.requested.count`                        |
| `portal.cmr.files.success`                        | `portal.cmr.files.success.count`                          |
| `portal.cmr.files.notfound`                       | `portal.cmr.files.notfound.count`                         |
| `portal.cmr.files.downloadedBytes`                | `portal.cmr.files.downloaded.bytes`                       |
| `portal.cmr.storage.zip.created`                  | `portal.cmr.storage.zip.created.count`                    |
| `portal.cmr.storage.zip.destroyed`                | `portal.cmr.storage.zip.destroyed.count`                  |
| `watchdog.webservices.events.received.start`      | `watchdog.webservices.events.received.start.count`        |
| `watchdog.webservices.events.received.stop`       | `watchdog.webservices.events.received.stop.count`         |
| `watchdog.webservices.events.received.ignored`    | `watchdog.webservices.events.received.ignored.count`      |
| `watchdog.client.events.startConnection`          | `watchdog.client.events.start.connection.count`           |
| `watchdog.viewer.start.succeeded`                 | `watchdog.viewer.start.succeeded.count`                   |
| `watchdog.viewer.start.failed`                    | `watchdog.viewer.start.failed.count`                      |
| `watchdog.viewer.signalingConnection.succeeded`   | `watchdog.viewer.signaling.connection.succeeded.count`    |
| `watchdog.viewer.launchQueue.count`               | `watchdog.viewer.launch.queue.count`                      |
| `watchdog.viewer.notResponding.count`             | `watchdog.viewer.not.responding.count`                    |
| `watchdog.viewer.start.duration.seconds`          | `watchdog.viewer.start.duration.milliseconds`             |

This release also adds a large number of new metrics, including import counters,
session and preload gauges, stream metrics and host hardware readings. See
[Observability](/UDiTH%20Portal/Observability) for the complete list.

### Render server and Portal must be updated together

The communication between Portal and the render server changed in this release.
Run the same release on Portal and on all render servers; a mixed setup is not
supported.

### Folder permissions are now split by purpose

A folder permission is no longer a single access level. It is granted separately
for streaming (browser-based viewing), local caching and opening a model locally.
Existing permissions are converted during the update so that a user who had
access keeps access to all three. Review the result in
[Permission Management](/UDiTH%20Portal/Permission%20Management) if a more
restrictive setup is wanted.
