Start with the gateway’s own check, then find what you see in the sections below. Each row links to the guide for
your install, which has the details. If nothing here fixes it, Support says what to send us.
| Install | What to run |
|---|
| Your own server | In the install folder: docker compose exec gateway portward --config /config/portward.toml doctor |
| Azure | In the portal, open VM → Run command → RunShellScript and run portward-azure doctor |
| AWS | Open https://<your gateway>/health and https://<your gateway>/ready in a browser, then the stack’s Logs output (CloudWatch). The stack gives no shell into the gateway, so doctor doesn’t run on AWS. |
| Google Cloud | Open https://<your gateway>/health, then the serial console (lines starting portward:) and terraform output logs |
doctor checks the gateway from the outside, the way Claude and ChatGPT reach it: the HTTPS certificate, your
directory, both connectors’ sign-in, the data sources and the records. Each line is marked ok, warn or FAIL
and says what to fix. The last line is “All checks passed.” or the number of “problem(s) to fix”.
/health answers {"ok": true, ...} with the gateway’s version when the gateway runs. /ready answers
{"ready": true, ...} with each of its checks: the settings, the records file and its changes, the gateway key, the
license key, the release and the logs. Neither checks your data sources, so both stay ok while a database is down.
On AWS, a database that stops answering shows up only as a failing question.
Neither doctor nor /health can see what your directory has registered. A passing check doesn’t prove that the
app’s redirect address is right there. If sign-in stops with an error at your directory, see
Sign-in fails.
| What you see | What to do |
|---|
doctor says “didn’t answer” | The containers aren’t running (docker compose ps), or a firewall blocks the server. Your own server |
| On AWS, the stack fails at the Service | The task couldn’t start. Look at the stack’s Logs output, or ECS → the cluster → stopped tasks → Stopped reason. Often the subnets can’t reach the internet (public IP DISABLED without a NAT gateway). AWS |
| On AWS with the relay, the address doesn’t answer | The relay log stream (relay/...) says whether the relay accepted the license key. If it didn’t, update the stack with the right one. AWS |
On Azure, /health doesn’t answer after 10 minutes | Run journalctl -u portward through Run command. “Key Vault answered … waiting for access” is normal while Azure applies the identity’s access to the vault. Portward’s start-up on the VM tries again every 15 seconds, for up to 10 minutes. If it then logs “can’t read … from Key Vault”, check that the identity portward-gateway has Key Vault Secrets Officer on the vault. Azure |
| On Google Cloud, the serial console says “waiting for secret” | Add that secret. Google Cloud, step 3 |
On Google Cloud, /health doesn’t answer over the relay | Check that the license key is current. A reissued key replaces the old one: update license_key. Google Cloud |
On Google Cloud, /health doesn’t answer at your domain | DNS isn’t pointing at ip_address yet. Google Cloud |
| What you see | What to do |
|---|
doctor says “no valid HTTPS certificate yet” | DNS isn’t pointing at the server yet, or ports 80 and 443 are closed. docker compose logs https shows Caddy’s attempts. Your own server |
| On Azure, a certificate error on your own domain | Check that the DNS record points at dnsTarget, and that nothing in front of the VM blocks ports 80 and 443. Azure |
| On Azure, a certificate error on the relay | Check that the license key in the Key Vault (license-key) is current, then run systemctl restart portward. docker compose logs relay shows the relay connection. Azure |
| On AWS with the relay, the stack fails at the Service and the gateway log looks fine | Caddy got no certificate, and the https/... log stream says why. If it names a rate limit, that is Let’s Encrypt’s: 5 certificates for the same address every 7 days. Each new stack asks for a new one. The message says when you can try again. AWS |
| What you see | What to do |
|---|
| Sign-in says the redirect address doesn’t match | Your sign-in app’s redirect URI must be exactly the gateway’s: <address>/auth/callback on AWS and your own server, the signInRedirect output on Azure, terraform output redirect_uri on Google Cloud. Sign-in setup |
| On AWS, sign-in shows an error at your directory | The app’s redirect address isn’t exactly <address>/auth/callback, or the client id is wrong. Okta, for example, answers 400 Bad Request and says the redirect_uri parameter must be a Login redirect URI in the client app settings. AWS |
doctor says the sign-in provider “didn’t answer” | The directory address (with WorkOS, issuer) is wrong, or the server can’t reach the internet. Your own server |
doctor says “no app secret” | Put the app’s secret in .env as PORTWARD_DIRECTORY_SECRET and restart. Sign-in setup |
doctor says “discovery at … doesn’t name” | public_url in portward.toml doesn’t match the address people use. Your own server |
| Claude’s sign-in fails before your company’s sign-in page opens | Remove the connector and add it again with Register automatically under OAuth client. Use it in Claude and ChatGPT |
| Claude shows the connector with Disconnect and This connector has no tools available | Claude kept an old sign-in for that address, for example from before the gateway was reinstalled. Select Disconnect, reload the page, then select Connect and sign in. Use it in Claude and ChatGPT |
With WorkOS, Claude says it can’t connect, but doctor passes | Check that both connector addresses are in WorkOS’s Resource Indicators exactly, with https:// and no trailing slash. Your own server |
| What you see | What to do |
|---|
| A page that says “Not allowed” after you sign in | You aren’t in that connector’s users or admins yet. Your Portward admin adds you. Use it in Claude and ChatGPT |
doctor warns “nobody is an admin yet” | Sign in through the admin connector, find your id in the log and add it to admin_subjects. Your own server, step 4 |
| The log says “connector refused … signed in, but not allowed” | The line names the id that was refused and the setting to add it to. On Google Cloud, add it to admin_subjects or users and apply. Google Cloud |
| On AWS, you’re refused after you sign in | The log names the groups your directory sent. Fix Admin groups or User groups: Entra sends Object IDs, not names, and Okta needs the groups scope and claim. AWS |
doctor warns that “anyone … signs in can use the data connector” | List who may in users = [...] under [auth]. Your own server, step 6 |
| What you see | What to do |
|---|
| Claude or ChatGPT can’t connect | Open https://<your gateway>/health in a browser. If it doesn’t answer, see The gateway doesn’t answer. |
| Claude shows only text, no table | A Claude owner may have turned off the query tool’s interactive view. Turn it back on in Organization settings, then Connectors. Use it in Claude and ChatGPT |
A question about a source that worked before fails after about 10 seconds with “query failed: …” and ConnectionTimeout or OperationalError | The gateway can’t reach the database any more. It waits 10 seconds to connect. A query that connects but runs too long stops at the query time limit instead. Check that the database is running and that its firewall or security group still lets the gateway in. On AWS, that is the port from the stack’s TaskSecurityGroup. Connect a source |
| The results table says “Real values aren’t available here” | Ask the question again in the chat. Use it in Claude and ChatGPT |
| ChatGPT’s calls fail after a Portward update | A workspace admin refreshes the connector’s tool list. Use it in Claude and ChatGPT |
| What you see | What to do |
|---|
portward update ends with exit code 1, 2 or 3 | 1: the new release wasn’t ready and the previous one runs again. 2: refused, nothing changed. 3: the previous release isn’t ready either, so send the output to Support. Update and back up |
| On AWS, the stack fails at RestoredStorage | Its status reason says why. If the file system “isn’t encrypted”, restore the recovery point again with Enable encryption. Otherwise no file system has that id in this account and region. AWS |
| On AWS, the stack fails at RestoredRecords | Its status reason gives the restore task’s exit code, and the restore/... log stream says why. Restore again into a new file system. AWS |
| The console’s Overview says “Logs need attention” | A row in the records file was edited, deleted or reordered since it was written. The gateway keeps running and answering. Restore an earlier backup to compare, and check who can write to the records. Update and back up |