adorable-balloon-99556
02/19/2026, 5:56 PMbrief-honey-45610
02/27/2026, 7:13 PMAPP_ORIGIN and API_HOST, GrowthBook requires a JWT_SECRET to be explicitly set. Make sure the API deployment has JWT_SECRET set to a long random string, and that it matches across all deployments that need to communicate.
2. Ensure both the APP_ORIGIN and API_HOST environment variables are correctly set and that the domains are considered "same site" (same root domain).
3. If your stats engine deployment is communicating with the API using a SECRET_API_KEY environment variable, note that this key defaults to readonly role. If more permissions are needed, you can set SECRET_API_KEY_ROLE accordingly.adorable-balloon-99556
02/27/2026, 8:02 PMJWT_SECRET properly set for all deployments.
2. Interesting. Now I believe the issue lays in here.
3. I am not using SECRET_API_KEY
About origin and host, a quick context on it:
We have 3 different deployments:
1. Internal
2. External
3. Frontend
Each of them have API_HOST set with a different value. They all have the same APP_ORIGIN though. And I have just realized we did not set API_HOST for the stats engine deployment. However, I am wondering if the stats engine could have its own origin as well.microscopic-smartphone-11811
02/27/2026, 8:29 PMadorable-balloon-99556
02/27/2026, 11:58 PMmicroscopic-smartphone-11811
03/02/2026, 5:42 PMPYTHON_SERVER_MODE=true set on the stats server? If it's not, the /stats endpoint won't be available and the router would essentially try to serve the other app endpoints which require a JWT token from the client but no JWT token is sent by app backends for /stats requests.adorable-balloon-99556
03/02/2026, 5:44 PMPYTHON_SERVER_MODE=true is set exclusively for the stats engine deploymentmicroscopic-smartphone-11811
03/02/2026, 5:46 PMadorable-balloon-99556
03/02/2026, 5:47 PMgrowthbook-stats-enginemicroscopic-smartphone-11811
03/02/2026, 5:49 PMadorable-balloon-99556
03/02/2026, 5:49 PM"true"microscopic-smartphone-11811
03/02/2026, 5:55 PMadorable-balloon-99556
03/02/2026, 5:55 PMmicroscopic-smartphone-11811
03/02/2026, 6:01 PMadorable-balloon-99556
03/02/2026, 6:03 PMadorable-balloon-99556
03/02/2026, 6:04 PMadorable-balloon-99556
03/02/2026, 6:04 PMmicroscopic-smartphone-11811
03/02/2026, 6:07 PMmicroscopic-smartphone-11811
03/02/2026, 6:08 PMmicroscopic-smartphone-11811
03/02/2026, 6:09 PMadorable-balloon-99556
03/02/2026, 6:10 PMmicroscopic-smartphone-11811
03/02/2026, 6:13 PMmicroscopic-smartphone-11811
03/02/2026, 6:13 PMmicroscopic-smartphone-11811
03/02/2026, 6:15 PMadorable-balloon-99556
03/02/2026, 6:18 PMk stands for kubectladorable-balloon-99556
03/02/2026, 6:19 PMmicroscopic-smartphone-11811
03/02/2026, 6:28 PMadorable-balloon-99556
03/02/2026, 6:30 PMmicroscopic-smartphone-11811
03/02/2026, 6:30 PMadorable-balloon-99556
03/02/2026, 6:32 PMPYTHON_SERVER_URL applied;
⢠My test was edit an experiment in the frontend (I actually ran the results query) and see the erroradorable-balloon-99556
03/02/2026, 6:32 PMmicroscopic-smartphone-11811
03/02/2026, 6:35 PMkubectl exec growthbook-stats-engine-67bd784bfc-kfddb -- curl -s -X POST
<http://localhost:3100/stats> -H "Content-Type: application/json" -d '{}'microscopic-smartphone-11811
03/02/2026, 6:35 PMadorable-balloon-99556
03/02/2026, 6:36 PMadorable-balloon-99556
03/02/2026, 6:36 PMmicroscopic-smartphone-11811
03/02/2026, 6:37 PMmicroscopic-smartphone-11811
03/02/2026, 6:37 PMmicroscopic-smartphone-11811
03/02/2026, 6:37 PMadorable-balloon-99556
03/02/2026, 6:39 PMroot@growthbook-stats-engine-67bd784bfc-kfddb:/usr/local/src/app# wget --post-data='{}' --header 'Content-Type:application/json' -O- <http://localhost:3100/stats>
--2026-03-02 18:38:52-- <http://localhost:3100/stats>
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:3100... connected.
HTTP request sent, awaiting response... 200 OK
Length: 14 [application/json]
Saving to: 'STDOUT'microscopic-smartphone-11811
03/02/2026, 6:41 PMadorable-balloon-99556
03/02/2026, 6:42 PMroot@growthbook-fe-internal-56ddbb8896-bhvwz:/usr/local/src/app# wget --method POST --body-data='{}' --header='Content-Type:application/json' <http://localhost:3100/stats>
--2026-03-02 18:42:18-- <http://localhost:3100/stats>
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:3100... connected.
HTTP request sent, awaiting response... 401 Unauthorized
Username/Password Authentication Failed.adorable-balloon-99556
03/02/2026, 6:43 PMgrowthbook-fe-internal...adorable-balloon-99556
03/02/2026, 6:43 PMAPP_ORIGIN thoughmicroscopic-smartphone-11811
03/02/2026, 6:43 PMadorable-balloon-99556
03/02/2026, 6:43 PMadorable-balloon-99556
03/02/2026, 6:43 PMadorable-balloon-99556
03/02/2026, 6:44 PMmicroscopic-smartphone-11811
03/02/2026, 6:44 PMadorable-balloon-99556
03/02/2026, 6:45 PMadorable-balloon-99556
03/02/2026, 6:45 PMmicroscopic-smartphone-11811
03/02/2026, 6:45 PMadorable-balloon-99556
03/02/2026, 6:45 PMmicroscopic-smartphone-11811
03/02/2026, 6:46 PMmicroscopic-smartphone-11811
03/02/2026, 6:48 PMadorable-balloon-99556
03/02/2026, 6:48 PMEXTERNAL_PYTHON_SERVER_URLadorable-balloon-99556
03/02/2026, 6:49 PMmicroscopic-smartphone-11811
03/02/2026, 6:49 PMadorable-balloon-99556
03/02/2026, 6:49 PMmicroscopic-smartphone-11811
03/02/2026, 6:49 PMadorable-balloon-99556
03/02/2026, 6:50 PMmicroscopic-smartphone-11811
03/02/2026, 6:50 PMmicroscopic-smartphone-11811
03/02/2026, 6:51 PMmicroscopic-smartphone-11811
03/02/2026, 6:52 PMadorable-balloon-99556
03/02/2026, 6:53 PMadorable-balloon-99556
03/02/2026, 6:53 PMadorable-balloon-99556
03/02/2026, 7:00 PMmicroscopic-smartphone-11811
03/02/2026, 7:00 PMadorable-balloon-99556
03/02/2026, 7:01 PMmicroscopic-smartphone-11811
03/02/2026, 7:03 PMadorable-balloon-99556
03/02/2026, 7:03 PMmicroscopic-smartphone-11811
03/02/2026, 7:03 PMadorable-balloon-99556
03/02/2026, 7:04 PMmicroscopic-smartphone-11811
03/02/2026, 7:06 PMadorable-balloon-99556
03/02/2026, 7:06 PMmicroscopic-smartphone-11811
03/02/2026, 7:06 PMmicroscopic-smartphone-11811
03/02/2026, 7:07 PMadorable-balloon-99556
03/02/2026, 7:08 PMadorable-balloon-99556
03/02/2026, 7:08 PMmicroscopic-smartphone-11811
03/02/2026, 7:08 PMmicroscopic-smartphone-11811
03/02/2026, 7:09 PMmicroscopic-smartphone-11811
03/02/2026, 7:09 PMadorable-balloon-99556
03/02/2026, 7:10 PMmicroscopic-smartphone-11811
03/02/2026, 7:10 PMadorable-balloon-99556
03/02/2026, 7:17 PM/statsadorable-balloon-99556
03/02/2026, 7:17 PM/healthcheck and /api/features/sdk-xxx logs on the stats engine deploymentadorable-balloon-99556
03/02/2026, 7:21 PMgrowthbook {"level":50,"time":1772478989927,"pid":94,"hostname":"growthbook-fe-internal-58f775bcc8-sv25r","dd":{"trace_id":"69a5e2080000000005aa242279c59e42","span_id":"5578905366920162470","service":"growthbook-frontend","version":"0.0.1","env":"production-enduser"},"msg":"Error fetching from stats engine: Stats server errored with: 401 - Unauthorized"}
growthbook {"level":50,"time":1772478989929,"pid":94,"hostname":"growthbook-fe-internal-58f775bcc8-sv25r","dd":
{"trace_id":"69a5e2080000000005aa242279c59e42","span_id":"5578905366920162470","service":"growthbook-frontend","version":"0.0.1","env":"production-enduser"},"err":{"type":"Error","message":"Stats server errored with: 401 - Unauthorized","stack":"Error: Stats server errored with: 401 - Unauthorized\n at runStatsEngine (/usr/local/src/app/packages/back-end/dist/services/stats.js:90:19)\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async runSnapshotAnalysis (/usr/local/src/app/packages/back-end/dist/services/stats.js:122:23)\n at async analyzeExperimentResults (/usr/local/src/app/packages/back-end/dist/services/stats.js:436:49)\n at async ExperimentResultsQueryRunner.runAnalysis (/usr/local/src/app/packages/back-end/dist/queryRunners/ExperimentResultsQueryRunner.js:290:60)\n at async ExperimentResultsQueryRunner.refreshQueryStatuses (/usr/local/src/app/packages/back-end/dist/queryRunners/QueryRunner.js:250:26)\n at async Timeout._onTimeout (/usr/local/src/app/packages/back-end/dist/queryRunners/QueryRunner.js:55:38)"},"msg":"Queries succeeded, failed running analysis"}adorable-balloon-99556
03/02/2026, 7:24 PMmicroscopic-smartphone-11811
03/02/2026, 7:25 PMadorable-balloon-99556
03/02/2026, 7:25 PMmicroscopic-smartphone-11811
03/02/2026, 7:28 PMadorable-balloon-99556
03/02/2026, 7:29 PM--body-data or --post-data) I get either 200 or 401.
I have never used wget like this before so I might be messing something upmicroscopic-smartphone-11811
03/02/2026, 7:33 PMwget --post-data='{}' --header 'Content-Type:application/json' -O-
<http://growthbook-stats-engine.growthbook.svc.cluster.local/stats>adorable-balloon-99556
03/02/2026, 7:50 PM--2026-03-02 19:50:45-- <http://growthbook-stats-engine.growthbook.svc.cluster.local/stats>
Resolving growthbook-stats-engine.growthbook.svc.cluster.local (growthbook-stats-engine.growthbook.svc.cluster.local)... fd65:3134:a4e::4:22fb
Connecting to growthbook-stats-engine.growthbook.svc.cluster.local (growthbook-stats-engine.growthbook.svc.cluster.local)|fd65:3134:a4e::4:22fb|:80... connected.
HTTP request sent, awaiting response... 401 Unauthorized
Username/Password Authentication Failed.microscopic-smartphone-11811
03/02/2026, 8:14 PMadorable-balloon-99556
03/02/2026, 8:14 PMadorable-balloon-99556
03/02/2026, 8:21 PMmicroscopic-smartphone-11811
03/02/2026, 8:23 PMmicroscopic-smartphone-11811
03/04/2026, 6:29 PMadorable-balloon-99556
03/04/2026, 7:26 PM