Skip to main content
A finished install passes every health check and can still fail the first time someone uses it. Each item on this page fails late, after the deploy looks done, and most of them fail in the browser, where no server-side test sees them. Work through them in order before your first build.

Allow your origin for CORS

The API answers cross-origin requests only from the origins in CORS_WHITELISTED_URLS, in values/jedify-be.yaml. With ENV=production, the API’s built-in list holds Jedify’s own domains, not yours. The install set CORS_WHITELISTED_URLS to your application host, https://<your application host>, which is the origin the web app runs on. If it’s wrong, the page loads and the user signs in, and then the browser blocks every API call. Nothing fails on the server, and the same calls answer 200 to curl. To verify, send a browser-style preflight request from your origin. Expected: 200. An origin that isn’t allowed gets 400.
To change it, edit the CORS_WHITELISTED_URLS entry in values/jedify-be.yaml, then upgrade both application releases:

A cold start can look like a CORS error

Two kinds of slowness follow every rollout:
  • The first authenticated request of each new pod takes around 80 seconds: its caches are cold, and it makes its first round trip to Zitadel’s management API. After that, requests take well under a second. One slow first call after a rollout isn’t a fault.
  • The load balancer lags behind the pods. A new pod is ready before the load balancer’s own health checks mark it healthy, 30 to 90 seconds later.
In those windows the load balancer itself can answer a request with a 502, 503 or 504. A response from the load balancer carries no Access-Control-Allow-Origin header, so the browser’s console fills with No 'Access-Control-Allow-Origin' header is present for endpoints whose CORS is configured correctly. Before you change any CORS setting, check the status code. In the browser’s network panel, look at the failing request’s status; or call the same endpoint with curl and your origin:
If it answers 200 with an access-control-allow-origin header, CORS is fine and the earlier failure was timing. Retry after a minute.

Create the account record

This is a manual step today, and the first build fails without it.
A Zitadel organization isn’t yet a Jedify account. When someone signs in, your Zitadel organization’s ID becomes their account ID, but nothing creates the matching account record. So the first build, or the first question, fails in the launcher component after sign-in succeeded:
The record lives in the accounts collection of the application’s database. It needs: To find your organization’s ID:
Create the record with scripts/account-setup.sh from the bundle, which ships it from release 2026.10.12. It writes the record from inside the API pod, through the application’s own model. Write one or two sentences about your company for --brief: the application adds them to its prompts as company context. --business-model is one of B2B, B2C, B2G, C2C or B2B2C, and defaults to B2B. The script is safe to run twice.
Expected: created <your organization ID>, or already exists <your organization ID> when the record is already there. Add --context <name> to use a kubectl context other than the current one, and --namespace if the application isn’t in jedify-be. To check for the record without writing anything, run it with --check instead of --brief. It exits 0 when the record exists and 1 when it doesn’t.
The bundle doesn’t include the script. Run the same command in the API pod directly:
Expected: created <your organization ID>, or already exists <your organization ID>.
To verify after the record exists, check the launcher’s log for the error. Expected: 0.

Connect your data warehouse

Network

Your warehouse sees your installation’s addresses, not Jedify’s. The IP addresses listed on the hosted service’s connector pages don’t apply to a self-hosted installation.
  • Through Cloud NAT (a network OpenTofu created): allow the NAT’s addresses. Cloud NAT allocates them automatically, so check them again after any change to the NAT.
    The addresses are under autoAllocatedNatIps.
  • Through your own network’s egress (an existing network): ask your network team which addresses traffic leaves from.
  • Over a private connection to the warehouse: with egress masquerade on, allow your node subnet; with it off, allow your pod range.
Your egress firewall must also allow the warehouse’s own hosts. For Snowflake, run this in Snowflake and allow every host it returns, on the port it lists:
That includes the account host and its stage hosts on port 443, and the OCSP hosts on port 80. Snowflake’s drivers check certificate revocation over plain HTTP on port 80, so a firewall that allows only 443 still stalls the connection. A blocked call from the cluster hangs instead of failing fast, so a missing allowlist entry shows up as a connection test or a build that never finishes.

Authentication

  • Snowflake. Use key-pair authentication with a dedicated service user, exactly as Snowflake Data Connector describes. Skip its step about allowlisting Jedify’s IP addresses, and allow your own as described above.
  • BigQuery. The connector takes an uploaded credentials file: a service-account key, or a Workload Identity Federation configuration (external_account). It can’t use the pod’s own Workload Identity, even though the pods run as a Google service account. If you don’t want a long-lived key, use a Workload Identity Federation configuration. See BigQuery Data Connector.
  • A warehouse behind a private certificate authority. Turn on trustExtraCA, as A gateway behind a private certificate authority describes; it covers every endpoint the application calls.

Run the first build and check it

1

Confirm the background tasks are scheduled

The application’s periodic tasks run as CronJobs. Without them, regression runs never leave PENDING, and stuck jobs are never cleaned up.
Expected: automated-agents, check-component-jobs, kill-hanging-edits, kill-processing-inquiries, manage-regression-tests and refresh-semantic-dimensions, each with a recent LAST SCHEDULE (the daily one after its first run).
2

Connect your warehouse and build

Sign in as a user with the Tenant Admin role. Connect your warehouse under Settings → Data Connectors (see Data Connectors), then add the tables Jedify should learn from to the Semantic Catalog (see Adding tables). Jedify builds your Semantic Fusion™ model from them.
3

Check the logs while it builds

Expected: nothing under any heading. Each pattern has an entry in Troubleshooting.
4

Ask a first question

Ask a narrow question you know the answer to, such as a count for one day, and check both the answer and the SQL. See Ask Jedify.Expected: progress appears live while the question runs, and the answer matches your source. If progress doesn’t appear until you reload the page, realtime isn’t connected: see Realtime. If the question stays in progress for ever, check the models: see Verify the models.