ÖmerFİ
11/29/2025, 11:48 PMprefect concurrency-limit create foo 2
i get this error:
prefect.exceptions.PrefectHTTPStatusError: Client error '401 Unauthorized' for url '<http://somewhere/api/csrf-token?client=097997a4-ed98-4cc7-b219-2250a59c0150>'
Response: {'exception_message': 'Unauthorized'}
For more information check: <https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401>
i try to self host a prefect server. The server is running on http://127.0.0.1:4200. I use Caddy. My Caddyfile is below:
:80
reverse_proxy :4200
i have following envs set:
PREFECT_SERVER_API_AUTH_STRING
PREFECT_API_AUTH_STRING
PREFECT_API_URL (not pointing to localhost but public ip)Marvin
11/29/2025, 11:48 PMMarvin
11/29/2025, 11:52 PM/api/csrf-token before state-changing requests (like creating a concurrency limit).
- Since you’ve set PREFECT_SERVER_API_AUTH_STRING on the server, every API route (including /api/csrf-token) requires Authorization: Basic <base64(user:pass)>.
- A 401 there means the server did not receive valid Basic auth — either the client didn’t send it, it was the wrong value, or your proxy stripped it.
Quick checks and fixes:
1) Verify your client env (where you run the CLI)
- Use raw user:pass — do not base64-encode it yourself.
- Ensure you are NOT setting PREFECT_API_KEY (that’s for Cloud and takes precedence over PREFECT_API_AUTH_STRING).
- Ensure PREFECT_API_URL includes the /api path and points at your proxy hostname/IP.
Examples:
export PREFECT_API_URL="http://<public-ip>/api"
export PREFECT_API_AUTH_STRING="admin:pass"
unset PREFECT_API_KEY
Confirm the CLI sees these:
prefect config view --show-sources
Look for:
- PREFECT_API_URL (should be http://<public-ip>/api)
- PREFECT_API_AUTH_STRING (should show [redacted] but sourced from env)
- PREFECT_API_KEY should be unset
2) Make sure the server value matches exactly
On the server process:
export PREFECT_SERVER_API_AUTH_STRING="admin:pass"
This must match your client’s PREFECT_API_AUTH_STRING exactly (again, not base64).
3) Pass the Authorization header through Caddy
Caddy generally forwards headers, but being explicit avoids surprises. Try:
:80 {
reverse_proxy 127.0.0.1:4200 {
header_up Host {host}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Proto {scheme}
header_up Authorization {http.request.header.Authorization}
}
}
4) Test with curl through your proxy
- Without auth (should 401):
curl -i http://<public-ip>/api/health
- With auth (should 200):
curl -i -H "Authorization: Basic $(echo -n 'admin:pass' | base64)" \
http://<public-ip>/api/health
If the authorized curl still returns 401, the header isn’t reaching the server (proxy config). If it returns 200, your CLI env likely isn’t set as expected — double-check step 1.
5) Your CLI command is valid
We’ve verified:
prefect concurrency-limit create foo 2
is the correct command. Once the auth header reaches the server, it should succeed.
If you’re still stuck, please share:
- The relevant lines from prefect config view --show-sources (PREFECT_API_URL, PREFECT_API_AUTH_STRING, PREFECT_API_KEY)
- The result of the two curl commands above
- Your current Caddyfile snippet
I can help zero in from there.ÖmerFİ
11/30/2025, 12:02 AM