bitwarden/server · error · Exception

NoDomainHintProvided

Error message

NoDomainHintProvided

What it means

Thrown in AccountController.LoginAsync (line 170) when the IdentityServer authorization context parameters do not contain a 'domain_hint' key or its value is blank. The domain_hint identifies which organization's SSO configuration to use for login.

Source

Thrown at bitwarden_license/src/Sso/Controllers/AccountController.cs:170

        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "An error occurred during SSO prevalidation.");
            return InvalidJson("SsoInvalidIdentifierError");
        }
    }

    [HttpGet]
    public async Task<IActionResult> LoginAsync(string returnUrl)
    {
        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);

        // FIXME: Update this file to be null safe and then delete the line below
#nullable disable
        if (!context.Parameters.AllKeys.Contains("domain_hint") ||
            string.IsNullOrWhiteSpace(context.Parameters["domain_hint"]))
        {
            throw new Exception(_i18nService.T("NoDomainHintProvided"));
        }

        var ssoToken = context.Parameters[SsoTokenable.TokenIdentifier];

        if (string.IsNullOrWhiteSpace(ssoToken))
        {
            return Unauthorized("A valid SSO token is required to continue with SSO login");
        }

        var domainHint = context.Parameters["domain_hint"];
        var organization = await _organizationRepository.GetByIdentifierAsync(domainHint);
#nullable restore

        if (organization == null)
        {
            return InvalidJson("OrganizationNotFoundByIdentifierError");
        }

View on GitHub (pinned to e93b962371)

Solutions

  1. Ensure the authorize/redirect URL that starts the SSO flow always includes a non-empty domain_hint parameter.
  2. Verify the web client's SSO initiation code passes the organization identifier as domain_hint.
  3. Check that returnUrl is not URL-decoded or truncated before reaching LoginAsync.

Example fix

// before — client omits domain_hint
var authorizeUrl = $"/sso/login?returnUrl={encodedReturn}";
// after — include domain_hint in the authorize parameters
var authorizeUrl = $"/connect/authorize?domain_hint={orgIdentifier}&returnUrl={encodedReturn}&...";
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: ensure domain_hint is present before redirecting to /sso/login
if (string.IsNullOrWhiteSpace(domainHint))
    throw new InvalidOperationException("domain_hint is required for SSO login.");
var authorizeUrl = $"/connect/authorize?domain_hint={domainHint}&...";

Try / catch

try { await _accountController.LoginAsync(returnUrl); }
catch (Exception ex) when (ex.Message.Contains("NoDomainHintProvided"))
{ /* redirect to org selection page */ }

Prevention

When it happens

Trigger: A GET request to the Login endpoint with a returnUrl whose authorization context (from _interaction.GetAuthorizationContextAsync) has no 'domain_hint' parameter or an empty/whitespace one.

Common situations: The SSO login flow was initiated without the web client passing domain_hint in the authorize request; returnUrl was constructed incorrectly; the client deep-linked into /login without going through PreValidate which captures the domain hint; browser stripped query params.

Related errors


AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13). Data as JSON: /api/errors/93f1f4e7a49ba68c. Report an issue: GitHub.