Troubleshooting OIDC Single Sign-On (SSO) Login FailuresSummary<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } As OIDC is picking up the pace as compared to the other options like SAML, its crucial to add more details around this specifically when it comes to debugging the OIDC flow. This article covers OIDC SSO login debugging and related details. Section 1 outlines OIDC fundamentals and ServiceNow's role as the relying party; Section 2 provides step-by-step debugging procedures. Release<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } Applicable to All the previous releases Instructions<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } Issue / Symptom Users are unable to log in via OIDC (OpenID Connect) SSO, or the integration between the Identity Provider (IdP) and ServiceNow (Relying Party) fails during authentication, token exchange, or claims retrieval. Environment ServiceNow instances with Multiple Provider SSO (OIDC) configuredAffected plugin: Multi-Provider SSO / OAuth OIDC Cause OIDC SSO failures typically occur at one of these stages: Authorization redirect to the IdPUser authentication/consent at the IdPAuthorization code + state validationBackend (server-to-server) token exchangeOptional UserInfo endpoint call for additional claims A misconfiguration or error at any stage (clock skew, incorrect redirect URI, invalid client secret, scope mismatch, certificate issues, etc.) can break the login flow. OIDC Overview OIDC (Open ID Connect) is the latest and modern identity protocol that is built on Oauth2.0. Core Components: Here are the key components of standard OIDC flow - Core Purpose: Authentication protocol that lets applications verify user identity without handling passwordsKey Components: Identity Provider (IdP): The trusted service that knows the user (e.g., Google, Okta)Relying Party (RP): The application that needs to verify user identity (ServiceNow here)End User: The person trying to log in OIDC Flow (Authorization Code Flow) The flow below is the standard OIDC authorization code flow, shown with the specific parameters ServiceNow (as the Relying Party) sends and receives at each step. 1. Initial Request — App redirects user to the IdP User clicks "Login with Okta" (or other IdP). The app redirects the user to the IdP with: client_idredirect_uriscope (e.g., "openid profile email")state (for verification/CSRF protection)response_type=code 2. User Authentication — User authenticates at the IdP User logs in at the IdPIdP asks the user to consent to the requested scopes 3. Authorization Code Return — IdP redirects back to ServiceNow IdP redirects back to the app’s redirect_uri with: code (short-lived, one-time-use authorization code)state (same value passed initially, used for verification) 4. Token Exchange (Backend-only / Back-channel call) ServiceNow’s server sends a server-to-server request to the IdP to exchange the code for an ID Token: Endpoint: /tokencodeclient_idclient_secretredirect_urigrant_type=authorization_code IdP returns: ID Token (JWT containing user info)Access Token (mandatory)Refresh Token (optional) ServiceNow establishes the session once the ID Token is validated. 5. UserInfo Endpoint Call (Optional) ServiceNow’s server sends a request to the IdP using the Access Token to retrieve additional user claims: Endpoint: /userinfoHeader: Authorization: Bearer <access_token> IdP returns additional user claims about the user. Prerequisites Confirm the following system properties are enabled: glide.authenticate.multisso.enabled = truecom.snc.platform.security.oauth.is.active = true Confirm the OIDC provider is configured correctly in the oauth_oidc_entity table (client ID, client secret, authorization/token/userinfo endpoint URLs, and the OAuth API Script reference). Resolution / Debugging Steps Step 1: Enable SSO debug logging Set property: glide.authenticate.multisso.debug = trueReproduce the login issueReview System Logs > System Log > All for SSO-related errors Step 2: Capture outbound token exchange traffic Enable the following properties temporarily: glide.outbound_http.content.max_limit = 2000glide.outbound_http_log.override = trueglide.outbound_http_log.override.level = allglide.outbound_http.file.log.allow.all.fields = trueglide.outbound_http.text.content_types = application/x-www-form-urlencoded Reproduce the issue, then check System Logs > Outbound HTTP Requests (table: sys_outbound_http_log). Filter by the IdP hostname, or by "token" in the URL path, to isolate the token exchange request/response. Step 3 (advanced, non-production only): Add temporary debug logging For deeper visibility into the token exchange and claims, debug statements can be temporarily added around the postprocessAccessToken function logic used by the OauthUtil script include referenced in the OIDC entity's OAuth API Script field. Code change to be done to get additional debug logs - postprocessAccessToken: function(accessTokenResponse) { var contentType = accessTokenResponse.getContentType(); if (contentType && contentType.indexOf('application/json') != -1) { var tokenResponse = (new global.JSON()).decode(accessTokenResponse.getBody()); gs.debug("DebugOIDC:Response: " + JSON.stringify(tokenResponse)); //DEBUG var paramMap = accessTokenResponse.getparameters(); for (param in tokenResponse){ paramMap.put(param, tokenResponse[param].toString()); gs.debug("DebugOIDC:param: " + param + ", Response: " + tokenResponse[param].toString()); //DEBUG } } }, Once this change is done, you need to set this script include into Oauth OIDC entity record: Navigate to oauth_oidc_entity table, open the record corresponding to your OIDC IDP record (alternatively you can open the IDP record from the navigation, open the IDP record and navigate to the entity tab to get the same record).Once on the OIDC Entity record form view, open the Oauth API script selector field, search for OauthUtil script record which you modified above and select it. This will ensure the changes we did are now effectively getting applied and it would print the required debug details. Now reproduce the issue again, then open the system logs and search with "DebugOIDC" keyword to get the required debug logs like this: Doc reference - https://www.servicenow.com/docs/bundle/zurich-api-reference/page/integrate/outbound-web-services/ref... Caution: Do not edit the out-of-box OauthUtil script include directly in production. Use a cloned/customized script include or a sub-production instance for this step, and remove any added logging once debugging is complete. Editing OOB script includes is unsupported and will be overwritten on upgrade. Step 4: Review captured data Confirm the authorization code and state parameter are returned correctly from the IdP.Confirm the token endpoint call (POST to the IdP's /token endpoint) returns a valid access_token / id_token and HTTP 200.Decode the id_token (JWT) to verify expected claims (iss, aud, exp, sub) match the OIDC entity configuration. Important - Cleanup After troubleshooting, always disable the debug properties: glide.authenticate.multisso.debugglide.outbound_http_log.overrideglide.outbound_http.file.log.allow.all.fieldsglide.outbound_http.text.content_typesglide.outbound_http.content.max_limit (reset to default) These properties can log sensitive tokens and PII-bearing ID claims in plain text, and increase log volume/disk usage if left enabled.