> ## Documentation Index
> Fetch the complete documentation index at: https://docs.controlplane.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Trino

> Trino distributed SQL query engine — one coordinator plus a scalable stateless worker tier that joins PostgreSQL, MySQL, ClickHouse, MongoDB and Iceberg in one query, deployed into an existing single-location GVC. Nothing is required for a default install; catalog and login secrets come first.

## Overview

Trino is a distributed SQL query engine that queries data where it lives. This template deploys a Trino cluster — one coordinator plus a scalable worker tier — that connects to PostgreSQL, MySQL, ClickHouse, MongoDB and many other sources through **catalogs**, and joins across them in a single query without copying any data. Databases you already run on Control Plane are reachable over internal DNS, and Iceberg tables in object storage are reachable through the [Polaris](/template-catalog/templates/polaris) template.

Trino stores nothing itself, so the template has no volume set: a restart costs only the queries in flight, and uninstalling never touches the databases it queries.

<Note>
  This template deploys into an existing [GVC](/reference/gvc) that you already have — it does not create or manage a GVC. Every workload runs in each location of that GVC, so install Trino into a single-location GVC: coordinator and worker traffic happens on every query.
</Note>

### What Gets Created

| Resource | Name | Purpose | Optional |
| - | - | - | - |
| Workload | `RELEASE_NAME-trino` | Coordinator — plans queries, serves the Web UI and the JDBC/REST endpoint, tracks the workers (standard, always 1 replica, HTTP port `8080`) | — |
| Workload | `RELEASE_NAME-trino-worker` | Stateless query-execution tier (standard, `workers.replicas` replicas, port `8080`) | Not created when `workers.replicas: 0` |
| Secret | `RELEASE_NAME-trino-coordinator-config`, `RELEASE_NAME-trino-jvm`, `RELEASE_NAME-trino-node` | Rendered `config.properties`, `jvm.config` and `node.properties`, mounted into `/etc/trino` | — |
| Secret | `RELEASE_NAME-trino-worker-config` | Worker `config.properties` | Not created when `workers.replicas: 0` |
| Secret | `RELEASE_NAME-trino-catalog-NAME` | One per `catalogs[]` entry, mounted as `/etc/trino/catalog/NAME.properties` on every node (underscores in the name become hyphens in the secret name) | `catalogs[]` entries |
| Secret | `RELEASE_NAME-trino-password-authenticator` | Password-file authenticator settings, coordinator only | `auth.enabled: true` |
| Identity / Policy | `RELEASE_NAME-trino-identity`, `RELEASE_NAME-trino-policy` | One identity shared by both workloads; `reveal` on exactly the config and catalog secrets plus the credential and login secrets you created | — |

The chart never creates, modifies or deletes the secrets you create yourself — they are referenced by name only.

## Prerequisites

None for a default install. The image ships the `tpch`, `tpcds`, `memory` and `jmx` catalogs, so the cluster is queryable the moment it is ready.

Two features need secrets that must exist **before** you install or upgrade with them on. Secrets are org-level, so no `--gvc` flag is involved.

<Steps>
  <Step title="Catalog credentials (to query your own data sources)">
    One secret per credential a catalog needs. Use an [opaque secret](/guides/create-secret/opaque) for a single value, or a [dictionary secret](/guides/create-secret/dictionary) when one secret holds several values:

    ```bash theme={null}
    # one value — referenced without secretKey
    printf '%s' 'YOUR-DATABASE-PASSWORD' | cpln secret create-opaque --name PG_CREDENTIALS_SECRET_NAME --encoding plain -f -

    # several values — referenced with secretKey
    cpln secret create-dictionary --name MYSQL_CREDENTIALS_SECRET_NAME \
      --entry password='YOUR-DATABASE-PASSWORD'
    ```

    The sibling database templates already read their credentials from a dictionary secret with a `password` key, so you can reference that same secret instead of creating a new one. Set `catalogs[].secrets[].secretName` (and `secretKey` for a dictionary) to this name — see [Catalogs](#catalogs).
  </Step>

  <Step title="Login secrets (to enable authentication and public access)">
    Two opaque secrets: a bcrypt password file with one user per line, and a random string every node shares once authentication is on:

    ```bash theme={null}
    # password file — bcrypt, cost 8 or more, one user per line
    htpasswd -B -C 10 -n alice | cpln secret create-opaque --name PASSWORD_FILE_SECRET_NAME --encoding plain -f -

    # internal shared secret
    printf '%s' "$(openssl rand -hex 32)" | cpln secret create-opaque --name SHARED_SECRET_NAME --encoding plain -f -
    ```

    Set `auth.passwordFileSecretName` and `auth.sharedSecretName` to these names — see [Authentication](#authentication).
  </Step>
</Steps>

<Warning>
  **A missing secret wedges the install rather than failing it.** `cpln helm install` reports success, but a workload that references a secret that does not exist never starts — so `cpln logs` returns **zero lines**. The only place the missing secret is named is `status.versions[].message`:

  ```bash theme={null}
  cpln workload get-deployments RELEASE_NAME-trino --gvc GVC_NAME -o yaml
  ```

  Check `RELEASE_NAME-trino-worker` the same way. It is `get-deployments` — plain `cpln workload get` has no `versions` key. Create the missing secret and the deployment recovers on its own after several minutes, or run `cpln workload force-redeployment RELEASE_NAME-trino --gvc GVC_NAME` (and the same for the worker workload) to skip the wait.
</Warning>

## Installation

A default install needs no values — it runs unauthenticated, reachable only from inside the GVC, with the built-in demo catalogs:

```bash theme={null}
cpln helm install RELEASE_NAME oci://ghcr.io/controlplane-com/templates/trino \
  --version 1.0.0 --gvc GVC_NAME
```

Add your own catalogs and authentication with a values file (`-f`) — see [Configuration](#configuration).

<CardGroup cols={2}>
  <Card title="UI" href="/template-catalog/install-manage/ui" icon="laptop">
    Browse, install, and manage templates visually
  </Card>

  <Card title="CLI" href="/template-catalog/install-manage/cli" icon="terminal">
    Manage templates from your terminal
  </Card>

  <Card title="Terraform" href="/template-catalog/install-manage/terraform" icon={<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><g fill-rule="evenodd"><path d="M77.941 44.5v36.836L46.324 62.918V26.082zm0 0" fill="#5c4ee5"/><path d="M81.41 81.336l31.633-18.418V26.082L81.41 44.5zm0 0" fill="#4040b2"/><path d="M11.242 42.36L42.86 60.776V23.941L11.242 5.523zm0 0M77.941 85.375L46.324 66.957v36.82l31.617 18.418zm0 0" fill="#5c4ee5"/></g></svg>}>
    Declare templates in your Terraform configurations
  </Card>

  <Card
    title="Pulumi"
    href="/template-catalog/install-manage/pulumi"
    icon={<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" id="Pulumi-Icon--Streamline-Svg-Logos" height="24" width="24">
    <desc>
        Pulumi Icon Streamline Icon: https://streamlinehq.com
    </desc>
    <path fill="#f26e7e" d="M4.683025 13.3318c0.869125 -0.5018 0.870575 -2.1264 0.003225 -3.62865s-2.27504 -2.313275 -3.1441725 -1.811475C0.672945 8.3935 0.6715 10.0181 1.53885 11.52035c0.86735 1.502275 2.27505 2.313275 3.144175 1.81145Zm0.0052 3.2167c0.86735 1.502275 0.865925 3.126875 -0.003225 3.628675 -0.86915 0.5018 -2.2768275 -0.309225 -3.144175 -1.81145 -0.8673525 -1.50225 -0.8659075 -3.126875 0.003225 -3.628675 0.8691325 -0.5018 2.276825 0.309225 3.144175 1.81145Zm5.922875 3.4243c0.86735 1.50225 0.8659 3.126775 -0.003225 3.62875 -0.869125 0.501775 -2.27685 -0.309325 -3.1442 -1.81155 -0.867325 -1.50225 -0.865875 -3.12685 0.00325 -3.628675 0.869125 -0.5018 2.276825 0.309225 3.144175 1.811475Zm-0.001925 -6.845275c0.86735 1.50225 0.8659 3.12685 -0.003225 3.628675 -0.869125 0.5018 -2.276825 -0.309225 -3.144175 -1.811475 -0.86735 -1.50225 -0.8659 -3.12685 0.003225 -3.62865 0.869125 -0.501825 2.276825 0.3092 3.144175 1.81145Z" stroke-width="0.25"></path>
    <path fill="#8a3391" d="M22.45775 11.524125c0.86725 -1.502225 0.865925 -3.12685 -0.003225 -3.62865 -0.869125 -0.501825 -2.276825 0.3092 -3.144175 1.811475 -0.86735 1.50225 -0.8659 3.126825 0.003225 3.62865 0.869125 0.501825 2.276825 -0.3092 3.144175 -1.811475Zm0.000175 3.2151c0.869075 0.5018 0.870625 2.1264 0.003225 3.62865 -0.86735 1.50225 -2.27505 2.313275 -3.144175 1.81145 -0.869125 -0.5018 -0.870575 -2.126425 -0.003225 -3.62865 0.86735 -1.50225 2.27505 -2.313275 3.144175 -1.81145ZM16.536225 18.157875c0.86915 0.501825 0.8706 2.126425 0.00325 3.628675 -0.86735 1.502125 -2.275075 2.313225 -3.1442 1.81145 -0.869125 -0.50175 -0.870575 -2.126425 -0.003225 -3.62865 0.867375 -1.502275 2.27505 -2.3133 3.144175 -1.811475Zm-0.003325 -6.843775c0.869125 0.5018 0.870575 2.126425 0.003225 3.628675s-2.27505 2.313275 -3.1442 1.811475c-0.869125 -0.501825 -0.870575 -2.126425 -0.003225 -3.628675 0.86735 -1.502275 2.27505 -2.313275 3.1442 -1.811475Z" stroke-width="0.25"></path>
    <path fill="#f7bf2a" d="M15.138225 2.06721c0 1.003615 -1.40625 1.817215 -3.14095 1.817215 -1.7347 0 -3.14095 -0.8136 -3.14095 -1.817215C8.856325 1.06359 10.262575 0.25 11.997275 0.25c1.7347 0 3.14095 0.81359 3.14095 1.81721ZM9.2166 5.482375c0 1.003625 -1.40625 1.8172 -3.14095 1.8172 -1.7347 0 -3.14095 -0.813575 -3.14095 -1.8172s1.40625 -1.817225 3.14095 -1.817225c1.7347 0 3.14095 0.8136 3.14095 1.817225Zm8.71005 1.8172c1.7347 0 3.14095 -0.813575 3.14095 -1.8172s-1.40625 -1.817225 -3.14095 -1.817225c-1.7347 0 -3.14095 0.8136 -3.14095 1.817225s1.40625 1.8172 3.14095 1.8172Zm-2.788425 1.605625c0 1.003625 -1.40625 1.8172 -3.14095 1.8172 -1.7347 0 -3.14095 -0.813575 -3.14095 -1.8172 0 -1.0036 1.40625 -1.8172 3.14095 -1.8172 1.7347 0 3.14095 0.8136 3.14095 1.8172Z" stroke-width="0.25"></path>
    </svg>}
  >
    Declare templates in your Pulumi programs
  </Card>
</CardGroup>

## Configuration

### Image

```yaml theme={null}
image: trinodb/trino:483
```

One image runs both tiers. The chart is shipped and tested on Trino 483.

### Coordinator

```yaml theme={null}
coordinator:
  resources:
    minCpu: 500m
    maxCpu: 1000m
    minMemory: 2Gi
    maxMemory: 4Gi # JVM heap is a percentage OF THIS — see jvm.maxRAMPercentage
```

There is exactly one coordinator per cluster — open-source Trino supports no more.

### Workers

```yaml theme={null}
workers:
  replicas: 1 # 0 = single-node mode (the coordinator executes queries itself)
  resources:
    minCpu: 500m
    maxCpu: 2000m
    minMemory: 2Gi
    maxMemory: 4Gi # JVM heap is a percentage OF THIS — see jvm.maxRAMPercentage
```

Raise `workers.replicas` for more query capacity and to keep capacity through a rolling restart. For both tiers the chart refuses to render unless `maxMemory` is whole GiB and at least `2Gi`, `minMemory` does not exceed `maxMemory`, and `maxCpu:minCpu` is at most 4:1; the error names the value to fix. Worker resources are only checked when `workers.replicas` is above `0`.

### JVM

```yaml theme={null}
jvm:
  maxRAMPercentage: 70
```

The heap is this percentage of each tier's `maxMemory` (allowed range 40–80). Trino derives its per-node query memory (30% of heap) and headroom (30% of heap) from it, so `maxMemory` is normally the only number you change. Capacity AI is off on both workloads, because the JVM sizes its heap once from the container limit at startup.

### Catalogs

```yaml theme={null}
catalogs: []
# catalogs:
#   - name: pg # queried as pg.<schema>.<table>
#     properties: |
#       connector.name=postgresql
#       connection-url=jdbc:postgresql://my-postgres.my-gvc.cpln.local:5432/postgres
#       connection-user=postgres
#       connection-password=${ENV:PG_PASSWORD}
#     secrets:
#       - env: PG_PASSWORD
#         secretName: my-postgres-credentials # must exist BEFORE install
#         secretKey: password # omit for an opaque secret (uses its payload)
#   - name: mysql
#     properties: |
#       connector.name=mysql
#       connection-url=jdbc:mysql://my-mysql.my-gvc.cpln.local:3306
#       connection-user=root
#       connection-password=${ENV:MYSQL_PASSWORD}
#     secrets:
#       - env: MYSQL_PASSWORD
#         secretName: my-mysql-credentials
#         secretKey: password
```

Each entry renders one secret and mounts one file at `/etc/trino/catalog/NAME.properties` on the coordinator and every worker. Credentials never go into `properties`: the file holds only a `${ENV:NAME}` placeholder, and the `secrets` list injects the value from a secret you created as that environment variable.

| Field | Description |
| - | - |
| `name` | Catalog name, queried as `name.schema.table`. Lowercase letters, digits and underscores, starting with a letter; unique; `system` is reserved. |
| `properties` | The connector properties file, copied from the connector's documentation page. Must contain a `connector.name=` line. |
| `secrets[].env` | `UPPER_SNAKE_CASE` environment variable name, referenced from `properties` as `${ENV:NAME}`. Must be unique across all catalogs. |
| `secrets[].secretName` | The secret holding the credential. It must exist **before** install. |
| `secrets[].secretKey` | Key within a dictionary secret. Omit it for an opaque secret, whose payload is used. |

The chart rejects any entry that breaks these rules at render, before anything is installed. Worked entries for the sibling templates are in [Connecting Data Sources](#connecting-data-sources).

### Authentication

```yaml theme={null}
auth:
  enabled: false
  passwordFileSecretName: "" # opaque secret, payload = bcrypt password file (e.g. my-trino-passwords)
  sharedSecretName: "" # opaque secret, payload = random string shared by all nodes (e.g. my-trino-shared-secret)
```

`auth.enabled` turns on password-file login on the coordinator and the shared secret the nodes use to authenticate to each other. Both secret names are required when it is on — create them first, as shown in [Prerequisites](#prerequisites).

<Warning>
  **Authentication and public access must be enabled together — the chart refuses either one alone.** Trino refuses password logins over plain HTTP, so an internal-only cluster with authentication on could not be queried by anyone; and an unauthenticated Trino on the internet would expose every connected data source. With both on, clients sign in over the public HTTPS endpoint. Without authentication, the internal firewall is the boundary.
</Warning>

### Access

```yaml theme={null}
publicAccess:
  enabled: false # true = Web UI + JDBC on the automatic *.cpln.app HTTPS endpoint; requires auth.enabled

internalAccess: # who may reach the coordinator from inside Control Plane
  type: same-gvc # options: same-gvc, same-org, workload-list ('none' breaks Trino — the coordinator calls itself over this path)
  workloads: [] # used with workload-list, e.g. //gvc/GVC_NAME/workload/WORKLOAD_NAME
```

| `internalAccess.type` | Who may reach the coordinator |
| - | - |
| `same-gvc` | Every workload in the same GVC (default). |
| `same-org` | Every workload in the same org. |
| `workload-list` | Only the workloads listed in `internalAccess.workloads`. The chart adds the coordinator and its own worker workload automatically, so list only your clients. |

`none` is rejected at render: the coordinator reaches itself through this same path, so it would fail every query. The worker tier always keeps its own firewall — only the coordinator and sibling workers may reach a worker, whatever you set here. Allow several minutes after changing an access setting before concluding it did not apply.

## Connecting

| What | Address | Notes |
| - | - | - |
| Web UI / JDBC / REST (public) | `status.canonicalEndpoint` of `RELEASE_NAME-trino` | `cpln workload get RELEASE_NAME-trino --gvc GVC_NAME -o yaml`; reachable while `publicAccess.enabled` is `true`. The Web UI is at `/ui/` |
| JDBC / clients (internal) | `jdbc:trino://RELEASE_NAME-trino.GVC_NAME.cpln.local:8080/tpch/tiny` | Plain HTTP, reachable per `internalAccess.type`; usable only while `auth.enabled` is `false` |
| REST API | `POST /v1/statement` on either address | The protocol the Trino CLI and drivers use |
| Credentials | A user from your password file | `cpln secret reveal PASSWORD_FILE_SECRET_NAME -o yaml` shows only the bcrypt hash — keep the plain passwords elsewhere. No credentials while `auth.enabled` is `false` |
| Built-in catalogs | `tpch`, `tpcds`, `memory`, `jmx`, `system` | Queryable on a default install |

Verify the cluster from inside the coordinator — the image ships the Trino CLI:

```bash theme={null}
cpln workload exec RELEASE_NAME-trino --gvc GVC_NAME --container trino -- trino --execute "SELECT count(*) FROM tpch.tiny.nation"
```

On a default internal-only install, open the Web UI through a tunnel and browse to `http://localhost:8080/ui/`; with no authentication configured, Trino asks only for a user name:

```bash theme={null}
cpln port-forward RELEASE_NAME-trino 8080:8080 --gvc GVC_NAME
```

The tunnel to this template has not been exercised in a test install. Once authentication is on, use the public endpoint instead: Trino refuses password logins over the plain-HTTP tunnel and the internal address alike.

### Connecting Data Sources

Point a catalog at any database Trino can reach. A sibling template in the same GVC is reachable at its fully qualified internal name, `WORKLOAD_NAME.GVC_NAME.cpln.local`:

| Template | Workload to point at | Port | Credential in its secret |
| - | - | - | - |
| [postgres](/template-catalog/templates/postgres) | its release name followed by `-postgres` | `5432` | `password` key |
| [mysql](/template-catalog/templates/mysql) | its release name followed by `-mysql` | `3306` | `password` key |
| [mariadb](/template-catalog/templates/mariadb) | its release name followed by `-maria` | `3306` | `password` key |
| [clickhouse](/template-catalog/templates/clickhouse) | its release name followed by `-clickhouse-server` | `8123` (HTTP interface) | `password` key |
| [mongodb](/template-catalog/templates/mongodb) | its release name followed by `-mongo` | `27017` | the whole connection URL, in a secret of its own |

```yaml theme={null}
catalogs:
  # postgres / postgres-highly-available / timescaledb / postgis
  - name: pg
    properties: |
      connector.name=postgresql
      connection-url=jdbc:postgresql://WORKLOAD_NAME.GVC_NAME.cpln.local:5432/postgres
      connection-user=postgres
      connection-password=${ENV:PG_PASSWORD}
    secrets:
      - env: PG_PASSWORD
        secretName: PG_CREDENTIALS_SECRET_NAME
        secretKey: password # omit for an opaque secret

  # mysql / mariadb / tidb — no database name in the URL
  - name: mysql
    properties: |
      connector.name=mysql
      connection-url=jdbc:mysql://WORKLOAD_NAME.GVC_NAME.cpln.local:3306
      connection-user=root
      connection-password=${ENV:MYSQL_PASSWORD}
    secrets:
      - env: MYSQL_PASSWORD
        secretName: MYSQL_CREDENTIALS_SECRET_NAME
        secretKey: password

  # clickhouse — HTTP interface on 8123
  - name: clickhouse
    properties: |
      connector.name=clickhouse
      connection-url=jdbc:clickhouse://WORKLOAD_NAME.GVC_NAME.cpln.local:8123/
      connection-user=default
      connection-password=${ENV:CLICKHOUSE_PASSWORD}
    secrets:
      - env: CLICKHOUSE_PASSWORD
        secretName: CLICKHOUSE_CREDENTIALS_SECRET_NAME
        secretKey: password

  # mongodb — credentials live inside the URL, so the whole URL is the secret (opaque)
  - name: mongo
    properties: |
      connector.name=mongodb
      mongodb.connection-url=${ENV:MONGO_URL}
    secrets:
      - env: MONGO_URL
        secretName: MONGO_URL_SECRET_NAME
```

Use the user name your database template was installed with in `connection-user`. With several catalogs configured, one statement spans all of them — including the built-in `tpch` data — and Trino performs the join itself:

```sql theme={null}
SELECT c.name, count(*) AS orders
FROM pg.public.orders o
JOIN mysql.shop.customers c ON c.id = o.customer_id
GROUP BY c.name;
```

**Iceberg tables in object storage** need a REST catalog, which this template does not bundle. Deploy the [Polaris](/template-catalog/templates/polaris) template against your bucket and add the `iceberg` catalog entry its page gives — Trino then creates, writes and queries Iceberg tables there. Hive and Delta Lake catalogs are not offered.

## Operations

### Adding or Changing a Catalog

Add the entry to your values and upgrade the release; create any secret it references first. Adding or removing a catalog changes both workloads, so they restart and the new catalog appears in `SHOW CATALOGS`:

```bash theme={null}
cpln helm upgrade RELEASE_NAME oci://ghcr.io/controlplane-com/templates/trino \
  --version 1.0.0 --gvc GVC_NAME \
  -f values.yaml
```

The values file must use the chart's nesting, exactly as the blocks in [Configuration](#configuration) show. A flat dotted key is accepted without error and silently changes nothing.

Editing the `properties` of an existing catalog changes only the content of its catalog secret, which a running replica does not re-read. After the upgrade, force a redeployment of both workloads:

```bash theme={null}
cpln workload force-redeployment RELEASE_NAME-trino --gvc GVC_NAME
cpln workload force-redeployment RELEASE_NAME-trino-worker --gvc GVC_NAME
```

### Rotating a Catalog Credential

Change the value by applying the whole secret — `cpln secret update` does not change values. For a dictionary secret:

```bash theme={null}
cat > rotate.yaml <<'EOF'
kind: secret
name: SECRET_NAME
type: dictionary
data:
  password: NEW-PASSWORD
EOF
cpln apply -f rotate.yaml
cpln secret reveal SECRET_NAME -o yaml
```

Keep every key the secret already has — the applied secret replaces its data. For an opaque secret use `type: opaque` with `data.encoding: plain` and `data.payload: NEW-VALUE`. A running replica keeps the old value until it restarts, so force a redeployment of `RELEASE_NAME-trino` and `RELEASE_NAME-trino-worker` as shown above. The same applies to the two login secrets.

### Scaling and Availability

* **Workers** are interchangeable: raise `workers.replicas` for capacity, and keep it at `2` or more if queries must keep running through a rolling restart. At the default of `1`, a worker restart empties the execution tier for its duration.
* **The coordinator** is a single point of failure — open-source Trino has one coordinator and no failover. Restarting it briefly interrupts all querying.
* **Queries are not retried.** A query running on a node that restarts or is replaced fails and must be resubmitted by the client.
* **Single node** — `workers.replicas: 0` removes the worker workload and the coordinator executes queries itself. Suitable for small or development installs.

### Troubleshooting

<AccordionGroup>
  <Accordion title="Deployment never becomes ready and the logs are empty">
    **Cause:** A catalog or login secret the workload references does not exist, so the container never starts.

    **Fix:** Read `status.versions[].message` with `cpln workload get-deployments RELEASE_NAME-trino --gvc GVC_NAME -o yaml` (and for `RELEASE_NAME-trino-worker`) — it names the missing secret. Create it; the deployment recovers on its own after several minutes, or force a redeployment.
  </Accordion>

  <Accordion title="Install fails with auth.enabled requires publicAccess.enabled">
    **Cause:** The chart only renders authentication and public access together. The mirror message, `publicAccess.enabled requires auth.enabled`, means the opposite half is missing.

    **Fix:** Set both `auth.enabled` and `publicAccess.enabled` to `true` with both login secret names, or leave both off.
  </Accordion>

  <Accordion title="Clients get 401 Password not allowed for insecure authentication">
    **Cause:** Authentication is on and the client connected over plain HTTP — the internal address or a port-forward tunnel. Trino accepts password logins only over HTTPS.

    **Fix:** Connect through the public canonical endpoint over HTTPS. For the JDBC driver that means port `443` with `SSL=true`.
  </Accordion>

  <Accordion title="An internal client cannot reach the coordinator">
    **Cause:** The coordinator's internal firewall does not admit the client. The client is outside the scope `internalAccess.type` allows — for example not listed under `workload-list`, or in another GVC under `same-gvc`.

    **Fix:** Add the client's workload link to `internalAccess.workloads`, or widen `internalAccess.type`, and upgrade. Allow several minutes for the change to apply.
  </Accordion>

  <Accordion title="A catalog password does not work">
    **Cause:** `secrets[].secretKey` does not match a key in the dictionary secret, a dictionary secret is referenced without `secretKey`, or the secret was rotated without a redeployment.

    **Fix:** Compare the key names with `cpln secret reveal SECRET_NAME -o yaml`, correct the catalog entry, and force a redeployment of both workloads.
  </Accordion>

  <Accordion title="Coordinator restarts after adding a catalog">
    **Cause:** Trino refuses to start on a catalog property it does not recognise, reporting `Configuration property 'NAME' was not used`.

    **Fix:** Find the property in the coordinator logs, then correct the `properties` block against the connector's documentation page:

    ```bash theme={null}
    cpln logs '{gvc="GVC_NAME", workload="RELEASE_NAME-trino"} |= "ERROR"' --limit 50 --since 10m
    ```
  </Accordion>

  <Accordion title="Queries fail with out-of-memory errors">
    **Cause:** Each query gets 30% of a node's heap, and the heap is `jvm.maxRAMPercentage` of `maxMemory`.

    **Fix:** Raise `maxMemory` on the tier doing the work first, then add workers. Raising `jvm.maxRAMPercentage` above about 75 makes it worse — the JVM needs the remainder outside the heap.
  </Accordion>
</AccordionGroup>

## Important Notes

* Authentication and public access are enabled together or not at all; with authentication on, every client signs in over the public HTTPS endpoint.
* Never put a password in a catalog's `properties` — reference it as `${ENV:NAME}` from a secret you created before installing.
* A rotated secret or an edited catalog takes effect only after a forced redeployment of both workloads.
* The coordinator is a single point of failure and in-flight queries are not retried; keep `workers.replicas` at `2` or more for restart tolerance.
* The built-in `jmx` catalog exposes JVM internals to anyone who can run a query.
* Uninstalling removes only the cluster — the databases it queried and the secrets you created are left in place.

## External References

<CardGroup cols={2}>
  <Card title="Trino Documentation" icon="book" href="https://trino.io/docs/current/">
    Official Trino documentation
  </Card>

  <Card title="Connectors" icon="plug" href="https://trino.io/docs/current/connector.html">
    Every available connector and its properties
  </Card>

  <Card title="JDBC Driver" icon="code" href="https://trino.io/docs/current/client/jdbc.html">
    Connect BI tools and applications over JDBC
  </Card>

  <Card title="Password File Authentication" icon="lock" href="https://trino.io/docs/current/security/password-file.html">
    How the bcrypt password file is used
  </Card>

  <Card title="Secrets in Properties Files" icon="key" href="https://trino.io/docs/current/security/secrets.html">
    The `${ENV:NAME}` substitution used by catalog credentials
  </Card>
</CardGroup>
