Skip to content
Udibo
On this page
View Markdown

Troubleshoot sign-in and API access

Follow the request from the browser to the identity service, back through your callback, and into the protected API. Fix the first boundary that fails. Keep state, PKCE, token verification, and CSRF enabled while diagnosing the problem. For problems a person reports about their own account, start with a user cannot sign in or recover.

Start with the symptom

If these checks do not isolate the problem, collect a minimal support report.

The sign-in page does not open

SymptomCheck next
No tenant or application accessConfirm your Udibo account and ask a tenant owner for dashboard access
Discovery failsCopy Issuer from the application's page and fetch its /.well-known/oauth-authorization-server document from the backend
Redirect URI rejectedCompare scheme, host, port, path, and query in the registration and application configuration
Local HTTP callback refusedUse a Development registration for a localhost web callback
invalid_clientCheck the client ID, secret, confidential-client setting, and environment; creating the registration does not create its secret
Sign-up unavailableCheck the tenant's sign-up mode and enabled sign-in methods; do not bypass a closed or waitlisted policy

The issuer is not the dashboard URL. A social provider's callback returns to the identity service; your application's callback receives the result from that service. They are two different registrations.

The user signs in but the callback fails

Unknown state or missing transient cookie: check whether the callback uses the same browser and application host that started the flow. Check cookie attributes, the pending-state secret, and whether every backend instance uses the same configuration and shared storage. Expired state should start a new login rather than being accepted without verification.

invalid_grant during the code exchange: an authorization code may be expired, already consumed, or paired with the wrong callback or PKCE verifier. Start a fresh flow and inspect the request's configuration. Do not replay a captured code or weaken verification to make it pass.

Login works on one instance only: the callback may arrive at a different instance. A process-local session or pending-state store cannot reliably serve that flow. See session readiness.

The app looks signed in but the API refuses

First identify whether the request goes through your BFF or directly to a bearer-token API. A BFF cookie request uses your application's session; a direct API request presents an access token. For Udibo APIs, choose the right API to check the host and credentials it accepts. Tenant-host APIs need the access token even when the person is already signed in on the hosted pages.

ResultCheck next
401 on a BFF cookie requestConfirm the request carries the application's session cookie and the backend can validate its access token
401 on a direct bearer API requestSend the access token in Authorization: Bearer …; check its expiry and the API's origin
403 with csrf_validation_failedFor a BFF cookie request, use BffClient or supply the configured CSRF header from a same-origin client
Valid token but missing API scopeCompare the requested scope with the client's allowed scope and the route's requirement
Valid token but missing application permissionCheck the role assignment and the organization or resource the operation actually targets
A profile field is missingRead UserInfo with profile or email as appropriate; an access token is not a full profile
A JWT is rejectedCheck the expected issuer, audience, signing key, algorithm, and expiry

In a BFF integration, keep tokens on the backend. Do not copy a bearer token into browser storage to work around a cookie problem. The BFF integration guide shows how the browser calls the application using its session cookie.

A role change seems to do nothing

Check where the answer came from. The browser's session projection may still contain the values captured during login. Authorize from the validated request or an appropriate live permission check, not that UI copy.

An offline JWT carries the claims from issuance until it expires. An opaque token can be introspected for current state, but your own caching can make that answer older. An active-organization claim is scoped to that organization; it does not answer a question about a different organization or a specific resource. See permissions and roles.

Refresh or logout behaves unexpectedly

For invalid_grant during refresh, check expiry, revocation, and whether two requests tried to rotate the same credential. Preserve atomic store updates and the package's rotation behavior. End the failed session and start login again instead of retrying a rejected refresh token indefinitely.

For sign-out, distinguish the application session from the identity service's session. A new login can return without another password prompt if the tenant's session is still valid. Test the exact local or SSO logout behavior your UI promises.

The sessions and sign-out guide distinguishes application sessions, tenant sessions, and device revocation, including the expected account-API refusals.

A user cannot sign in or recover

What the person reportsCheck next
No social button on the sign-in pageBoth Social sign-in under Security and the provider's own toggle must be on; see social login
"Sign up" is refusedCheck Settings → Sign-up → Self-serve sign-up. Closed or waitlisted registration requires a valid waitlist invitation for a new account; existing users can still sign in. Check whether the link expired, was replaced, or was denied
Too many failed attemptsA locked account sees the same error as a wrong password; the person can use the emailed unlock link or reset their password; see account protection
Lost their authenticator and recovery codesAn administrator resets MFA from the person's page under Users; see MFA
Their account is disabledA disabled account is refused everywhere until an administrator enables it; see manage users
Nowhere to turn on a dead-end pageSet a Support URL under Settings → Branding so those pages offer Contact support; see branding

The tenant's audit log records failed sign-ins, lockouts, and administrator actions with their times. Filter by the person to see what happened before changing their account.

Email does not arrive

  • Limits. Mail through Udibo's shared sender has a daily ceiling, and any email limit set on the Billing page stops sending when it is reached, sign-in codes and resets included. Check the Billing page first. The senders have separate monthly and daily limits; use usage, limits, and alerts to identify the affected sender and period before changing either limit.

  • Your own sender. Under Settings → Email, check the domain status and any health warning. An unreadable API key falls back to the shared sender; rejected sends mean the key or domain needs attention in Resend.

  • Suppressed addresses. A permanent bounce or spam complaint stops security notices, waitlist emails, and invitations to that address. Codes, links, and resets the person asks for are still sent.

  • Failed sends appear in the audit log as email.delivery_failed.

Sending email from your domain covers every email the service sends and how to test delivery.

Webhook deliveries fail

Open the endpoint's delivery log in the dashboard. It shows each delivery's status, attempts, last response code, and a truncated error. A signature mismatch almost always means the handler verified a parsed and re-serialized body instead of the raw request bytes, or used a rotated secret. See webhooks for verification, retries, and duplicate handling.

Bring useful information to support

Include the environment, the failing step, the HTTP status or error code, approximate time, runtime and package versions, and a minimal reproduction. Use the support channel you agreed with Udibo. Redact secrets, passwords, cookies, authorization codes, and token values. Callback URLs can contain credentials in the query string; report the registered URL rather than a captured login URL.

Next: return to your first sign-in or production readiness.

Last verified 2026-10-02.