Kareadita/Kavita · error · KavitaException

oidc-invalid-authority

oidc-invalid-authority

Error message

oidc-invalid-authority

What it means

Thrown while applying a change to the OIDC Authority. When the authority is changing to a non-empty value, UpdateOidcSettings calls IsValidAuthority, which (in non-dev) requires https, fetches '<authority>/.well-known/openid-configuration', and requires the returned issuer to exactly equal the authority. Any result other than Success (MissingHttps, Failure, InvalidAuthority) causes KavitaException('oidc-invalid-authority'). SettingsController returns HTTP 400 'OIDC authority is invalid'.

Source

Thrown at Kavita.Services/SettingsService.cs:634

        var currentConfig = JsonSerializer.Deserialize<OidcConfigDto>(setting.Value)!;

        // Patch Oidc Secret back in if not changed
        if ("*".Repeat(currentConfig.Secret.Length) == updateSettingsDto.OidcConfig.Secret)
        {
            updateSettingsDto.OidcConfig.Secret = currentConfig.Secret;
        }

        var newValue = JsonSerializer.Serialize(updateSettingsDto.OidcConfig);
        if (setting.Value == newValue) return false;

        if (currentConfig.Authority != updateSettingsDto.OidcConfig.Authority)
        {
            // Only check validity if we're changing into a value that would be used
            if (!string.IsNullOrEmpty(updateSettingsDto.OidcConfig.Authority)
                && await IsValidAuthority(updateSettingsDto.OidcConfig.Authority + string.Empty) != AuthorityValidationResult.Success)
            {
                throw new KavitaException("oidc-invalid-authority");
            }

            logger.LogWarning("OIDC Authority is changing, clearing all external ids");
            await oidcService.ClearOidcIds();
        }

        setting.Value = newValue;
        unitOfWork.SettingsRepository.Update(setting);

        return true;
    }

    private void UpdateEmailSettings(ServerSetting setting, ServerSettingDto updateSettingsDto)
    {
        if (setting.Key == ServerSettingKey.EmailHost &&
            updateSettingsDto.SmtpConfig.Host + string.Empty != setting.Value)
        {
            setting.Value = updateSettingsDto.SmtpConfig.Host + string.Empty;

View on GitHub (pinned to 9c3e540000)

Solutions

  1. Use the exact issuer URL reported by the provider's well-known endpoint (match trailing slash precisely).
  2. Ensure the authority uses https (required outside Development).
  3. Confirm the server can reach '<authority>/.well-known/openid-configuration' (egress/firewall/proxy/SSRF rules, valid TLS certs).
  4. Pre-validate with POST /api/settings/is-valid-authority and only submit the change when it returns Success.
  5. If developing locally, run in Development to relax the https requirement, but switch to https before production.

Example fix

// before
oidcConfig: { authority: 'http://idp.example.com' } // http in prod

// after
oidcConfig: { authority: 'https://idp.example.com/' } // matches issuer exactly
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate the authority before including it in the settings save.
const result = await api.post<AuthorityValidationResult>(
  '/api/settings/is-valid-authority',
  { authority: dto.oidcConfig.authority }
);
// AuthorityValidationResult: 0 Success, 1 InvalidAuthority, 2 Failure, 3 NotApplicable, 4 MissingHttps
if (result !== 0 /* Success */) {
  showError('OIDC authority is invalid (check https, issuer match, reachability)');
  return;
}
await api.post('/api/settings', dto);

Prevention

When it happens

Trigger: POST /api/settings changing oidcConfig.authority to an http URL (production build), an unreachable URL, a URL whose openid-configuration issuer does not match the authority exactly, a URL with a trailing-slash mismatch, or a provider behind a reverse proxy that blocks the server-side fetch (SSRF filter, self-signed cert, network egress restriction).

Common situations: Keycloak/Authelia/Authentik where the configured 'issuer' base URL differs from the authority typed; authority with/without trailing slash not matching issuer; corporate proxy blocking outbound fetch; provider temporarily down during save; using http in a production (non-Development) build.

Related errors


AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13). Data as JSON: /api/errors/3a167b88c775fc4d. Report an issue: GitHub.