# Troubleshooting

Common SAML errors and how to resolve them. Most apply to both self-hosted and cloud deployments unless noted.

***

## `422: Signups not allowed for this instance`

The user wasn't pre-provisioned. Self-registration is disabled by default.

Run `POST /sfp/api/users` (or `sfp server user add`) for the user — the endpoint links the SSO identity if the email already exists as an email/password user, so it's safe to re-run.

***

## `No such SSO provider` / `No SSO provider assigned for this domain`

The provider isn't registered, or the registered domain doesn't match the user's email domain.

```bash
curl "https://<your-domain>/sfp/api/sso/providers" \
  -H "Authorization: Bearer $SFP_JWT"
```

Check that:

* A provider is listed.
* Its `domains` array contains the user's email domain.
* The `id` matches what `/sfp/api/config` reports under `sso.providerId`.

For **cloud** deployments, also confirm with flxbl that the provider was registered at the global level — the local registration only stores the ID.

***

## `SAML 2.0 is disabled`

The CLI couldn't find SSO settings on the server.

1. Verify `--sfp-server-url` (or `SFP_SERVER_URL`) points at your public sfp server.
2. Run `curl https://<your-domain>/sfp/api/config` and confirm:
   * `deploymentMode` is `selfhosted` or `cloud` (matches your setup).
   * `sso.providerId` is a non-empty UUID.
   * `sso.domain` is set.

If `sso` is empty, the provider wasn't registered. See [Self-Hosted Setup → Step 2](/flxbl/sfp-server/setting-up/saml-authentication/self-hosted-setup.md#step-2--register-the-idp-with-sfp) or [Cloud Setup → Step 3](/flxbl/sfp-server/setting-up/saml-authentication/cloud-setup.md#step-3--store-the-provider-id-on-your-tenant).

***

## `/sfp/api/config` shows empty SSO

The provider record didn't make it into the local database.

* **Self-hosted**: re-run `POST /sfp/api/sso/providers` with the metadata URL.
* **Cloud**: re-run `POST /sfp/api/sso/providers` with the `providerId` field set to the UUID flxbl gave you.

Both calls are idempotent.

***

## Browser SAML callback hangs after IdP login

`sfp server auth login --provider saml` opens a local HTTP server on `127.0.0.1:54329` to receive the IdP's SAML response — the IdP redirects the browser to `http://localhost:54329/callback` after authentication. If a host firewall, VPN client, antivirus, or corporate proxy blocks loopback traffic on port 54329, the browser tab stalls on a blank page and the CLI never receives the token.

Verify nothing is listening on or blocking `127.0.0.1:54329` before invoking SAML login:

```bash
ss -tlnp | grep ':54329 '   # should be empty before login starts
```

***

## SAML entity ID has the wrong domain (self-hosted)

GoTrue builds the SAML entity ID from `API_EXTERNAL_URL`. For self-hosted deployments, this is derived from `AUTH_SUPABASE_EXTERNAL_URL` in docker-compose:

```yaml
API_EXTERNAL_URL: ${AUTH_SUPABASE_EXTERNAL_URL:-https://${DOMAIN}}/auth/v1
```

`/auth/v1` is appended **outside** the `AUTH_SUPABASE_EXTERNAL_URL` default expression. If you set `AUTH_SUPABASE_EXTERNAL_URL` yourself, set it to `https://<your-domain>` (no trailing path) — the `/auth/v1` suffix is added by compose. If your variable already includes `/auth/v1`, the resulting `API_EXTERNAL_URL` becomes `https://<your-domain>/auth/v1/auth/v1` and your IdP will reject the request.

For deployments created with `sfp server init`, this is set correctly automatically. If you've changed the public URL of your sfp server after init, re-run init or update the deployment's public URL setting so the SAML metadata reflects the new domain.

***

## Admin login fails after switching auth modes (self-hosted)

When converting from global auth (`AUTH_USE_GLOBAL_AUTH=true`) to self-hosted, three env vars must also point to the local Supabase instance:

| Variable                     | Self-hosted value               |
| ---------------------------- | ------------------------------- |
| `AUTH_SUPABASE_URL`          | `http://supabase-kong:8000`     |
| `AUTH_SUPABASE_EXTERNAL_URL` | `https://<your-domain>/auth/v1` |
| `AUTH_SUPABASE_ANON_KEY`     | Local `SUPABASE_ANON_KEY` value |

For fresh `sfp server init` deployments these are set correctly automatically.

***

## SSO login redirects to the IdP but fails to come back

The IdP successfully authenticated the user, but the SAML response landed somewhere it couldn't be processed.

* **Cloud**: the ACS URL in your IdP must be `https://auth.flxbl.io/auth/v1/sso/saml/acs` — not your tenant domain. Check **Basic SAML Configuration** in the IdP application.
* **Self-hosted**: the ACS URL must be `https://<your-domain>/auth/v1/sso/saml/acs`. The domain there must be the public URL of your sfp server.

***

## SAML entity ID has the wrong domain

The IdP rejects the AuthnRequest because the issuer doesn't match what was configured on the IdP side.

For self-hosted deployments created with `sfp server init`, this is set correctly automatically. If you've changed the public URL of your sfp server after `sfp server init`, re-run init or update the deployment's public URL setting so the SAML metadata reflects the new domain.

***

## User provisioned but SSO login still fails

The user exists in sfp but doesn't have an SSO identity linked to the registered IdP.

Re-run the same `POST /sfp/api/users` call. The endpoint is idempotent and will link the SSO identity if it's missing — no need to delete the user first.

***

## CI job fails with `401` after running for a while

SAML access tokens expire after about an hour. The CLI auto-refreshes them on `401` responses, but if your CI job pinned a specific token, force a refresh at the start of the job:

```bash
sfp auth refresh --email user@company.com
```

Or refresh every locally cached session:

```bash
sfp auth refresh --all
```

***

## Still stuck?

Capture the output of:

```bash
curl https://<your-domain>/sfp/api/config
curl "https://<your-domain>/sfp/api/sso/providers" \
  -H "Authorization: Bearer $SFP_JWT"
```

…along with the exact error message and the IdP-side audit log entry, and open a support request.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flxbl.io/flxbl/sfp-server/setting-up/saml-authentication/troubleshooting.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
