Why can’t the Control Plane connect to my AgentOS?
The Control Plane connects from your browser, not Agno's servers. Here are the six reasons a connection fails, how to tell which one you have, and how to fix each.
October 23, 20268 min read
Checked against the Agno docs and the AgentOS source on October 23, 2026.
The Control Plane at os.agno.com connects to your AgentOS straight from your browser, not from Agno's servers. The connection fails when your browser can't reach the runtime, or reaches it and gets refused. There are six common reasons: the browser blocks the request to localhost, AgentOS isn't running at the URL you entered, the server is listening only inside its own container, a live URL isn't HTTPS, authentication rejects the request, or a proxy in front of AgentOS strips the CORS headers. A single check narrows it down.
How do I find out what's wrong?
Open your AgentOS health endpoint in the same browser you use for the Control Plane, for example http://localhost:7777/health.
- It returns
{"status": "ok", ...}: the server is running and your browser can reach this route. This does not check databases or other API routes. Next, check browser permission, authentication and CORS. - It doesn't load: if the connection is refused or times out, check that AgentOS is running, then check the URL, the port and the host binding. If you get an HTTP error response, a server was reached; inspect the status and response for an AgentOS or proxy error.
The /health route bypasses AgentOS's built-in authentication. A reverse proxy or custom middleware can still protect or block it.
| Symptom | Likely cause | Fix |
|---|---|---|
Local AgentOS fails; /health loads | Browser blocking os.agno.com from reaching localhost | Allow local-network access for os.agno.com |
/health connection is refused or times out | AgentOS not running, wrong URL or port, or a network restriction | Start it; check the URL, port and network access |
| Works when run directly, fails in Docker or on a VM | Server bound to localhost | With serve(), set AGENT_OS_HOST=0.0.0.0; with direct Uvicorn, use --host 0.0.0.0. Publish the container port. |
Public AgentOS fails on an http:// URL | Browser blocks HTTP from an HTTPS page | Serve AgentOS over HTTPS |
| Connects, then "Authorization Failed" or 401 | Security key or JWT setup | Match the Control Plane's auth mode to the server's |
| Works directly, fails behind a proxy | Proxy strips CORS headers or blocks preflight | Pass OPTIONS and the CORS headers through |
Why does my browser block the connection to localhost?
Browsers restrict public websites from making requests to your own machine. When os.agno.com calls http://localhost:7777, the browser either asks for permission or blocks the request.
- Chrome and Edge: when os.agno.com asks for local-network access, select Allow. If you denied it before, open the site permissions for os.agno.com, allow local-network access, and reload.
- Firefox: select Allow when asked. To change an earlier answer, go to Settings › Privacy & Security › Permissions and update Device apps and services and Local network devices.
- Brave: allow localhost access for os.agno.com. If Shields still blocks it, turn Shields off for the site and refresh.
- Safari: it may block local connections regardless of your settings. Use a tunnel (see below) or another browser.
Is AgentOS running where the Control Plane is looking?
Check the URL and port first. agent_os.serve() listens on port 7777 by default, and the AGENT_OS_PORT environment variable overrides it. A bare uvicorn setup, including the agentos-docker template, usually listens on 8000. The Endpoint URL in the Control Plane has to match exactly, including the protocol.
If the server runs in Docker, on a VM, or on any machine other than the one your browser is on, check where it's listening. serve() binds to localhost by default, which means "this machine only." Inside a container, "this machine" is the container, so nothing outside it can connect. Bind to every interface instead:
export AGENT_OS_HOST=0.0.0.0If you launch Uvicorn directly, use --host 0.0.0.0 instead; AGENT_OS_HOST configures agent_os.serve(). Then publish the port from the container, for example with -p 7777:7777 when the server listens on 7777.
Why does a live AgentOS need HTTPS?
The Control Plane is served over HTTPS, and browsers block its requests to plain http:// endpoints on the public internet. Localhost and other loopback addresses are exceptions, and some browsers also allow permission-gated HTTP requests to local-network addresses. The Control Plane's Local environment accepts http://localhost:7777; use HTTPS for public deployments. Put a deployed AgentOS behind TLS, through your load balancer, platform or reverse proxy, before you connect it.
Why does it connect but then say "Authorization Failed"?
The browser reached AgentOS, and AgentOS rejected the credentials. A 401 means the credential is missing or invalid. A 403 means it's valid but lacks the scope for that endpoint. The usual causes are:
- The server has a security key the Control Plane doesn't. If
OS_SECURITY_KEYis set and JWT authentication is not configured, protected requests need that key. Add it to the connection in the Control Plane. - JWT authorization is on, but the server can't verify tokens. For Control Plane tokens, configure the public key for this specific OS connection in
JWT_VERIFICATION_KEY, or useJWT_JWKS_FILE. A wrong key causes signature verification to fail. Withauthorization=Trueand no verification-key source, the current SDK fails during app construction instead of starting and returning 401. Load the configuration before starting or restarting the server; editing.envdoesn't affect a process that's already running. - The algorithm doesn't match. Control Plane keys are always RS256, which is also the default. Any other
algorithmvalue fails every request. - The key got mangled. Multi-line PEM keys can lose their line breaks in environment variables, so a key that works on one machine fails on another. Load it from a file or a JWKS file instead.
- Both modes are on. JWT authentication takes precedence over the security key, so security-key requests fail; a valid JWT still works. Setting
JWT_VERIFICATION_KEYorJWT_JWKS_FILEenables JWT authentication even withauthorization=False;authorization=Truealso enables permission checks. To switch to security-key mode, disable authorization and remove JWT configuration, including both environment variables. Then restart the server and update the Control Plane connection. JWT with authorization is preferred because it gives you per-endpoint permissions.
Could CORS be the problem?
Rarely, if you run AgentOS directly. AgentOS always includes https://os.agno.com in its allowed origins, alongside any origins you add with cors_allowed_origins. Two things can still cause trouble:
- A proxy, gateway or CDN in front of AgentOS that strips the CORS response headers or rejects the browser's
OPTIONSpreflight request. Make sure both reach AgentOS untouched. - A wildcard origin. AgentOS removes
"*"from the allowed origins, so adding it won't let other origins through. List the exact origins you need.
Can I use a tunnel instead?
Yes. A tunnel gives your local AgentOS a public HTTPS URL, which avoids the localhost permission issue entirely. Run ngrok http 7777 or cloudflared tunnel --url http://localhost:7777, then paste the URL it prints into the Control Plane.
Before you do, note two things:
- Turn on authentication first. It's off by default, and a tunnel gives anyone on the internet a route to your runtime.
- Cloudflare's anonymous Quick Tunnels don't carry AgentOS's streamed responses (server-sent events). Use a named tunnel if you need streaming.
It's connected, so why don't I see my sessions or traces?
Your agents, teams and workflows appear as soon as the Control Plane connects, subject to their access permissions. Sessions and memory need the relevant feature configuration and a database on AgentOS or its agents, teams or workflows. Knowledge management needs a Knowledge instance with a contents database. For traces, set tracing=True and provide an AgentOS or component database; without either, tracing is skipped with a warning. If a list comes back empty with authorization on, check the token's scopes as well.
Sources
- AgentOS connection issues (browser permissions and tunnels)
- Connect your AgentOS (connection fields, Local and Live)
- Authorization quickstart (JWT setup and routes left open)
- Authorization failed (401 and 403 causes)
- AgentOS security overview (security key mode)
- AgentOS source, October 23, 2026: default allowed origins and wildcard removal (
agno/os/settings.py,agno/os/utils.py),serve()host and port defaults (agno/os/app.py)
Frequently asked questions
No. It connects directly from your browser to your runtime. Your AgentOS has to be reachable from the machine you’re browsing on, and your data doesn’t pass through Agno.
agent_os.serve() uses port 7777 by default, and AGENT_OS_PORT changes it. Setups that run uvicorn directly, like the agentos-docker template, usually use 8000.
Safari may block a public site from calling localhost regardless of your settings. Allow access in Chrome, Edge, Firefox or Brave, or use a tunnel with Safari.
serve() binds to localhost, which inside a container means the container only. Set AGENT_OS_HOST=0.0.0.0 when using serve(), or --host 0.0.0.0 when launching Uvicorn directly, and publish the port.
Use HTTPS for public production endpoints.
Check that the verification key belongs to this specific OS connection, the process was restarted after loading it, the algorithm is RS256, and the key kept its line breaks. Load a PEM key from a file in code if its formatting is being lost. Having OS_SECURITY_KEY set alongside JWT configuration does not invalidate a valid JWT; JWT takes precedence.

