SSO stopped working for all users this morning: diagnosis and fixes
This runbook is for teams whose single sign-on suddenly fails for everyone at once. It walks you through the fastest checks first—identity provider status, certificate expiry, redirect URL drift, DNS/TLS issues, and clock skew—then gives concrete fixes and verification steps.
TL;DR — If SSO broke for everyone at the same time this morning, the most likely causes are an expired signing certificate, a changed redirect/callback URL, or an outage/change at your identity provider (IdP, the service that logs users in). Start by checking your IdP status page and your app's SSO settings in the admin dashboard, then compare the current ACS/redirect URL and certificate expiry against yesterday's working values. Reading time: ~6 min
The scenario
It is 9:12 on a Tuesday and your support inbox is filling up. Every employee who normally clicks "Sign in with SSO" is getting bounced back to the login page, or they see an error like "invalid_response" or "AADSTS700016". Nothing else in the app looks down, your public site loads, and password-based local admin login may still work. The common thread is that every SSO user started failing this morning, at roughly the same time.
Symptoms
- Users click Sign in with SSO and are returned to your login page without being signed in.
- Users see one of these common messages:
SAML response is invalidInvalid audienceThe reply URL specified in the request does not match the reply URLs configured for the applicationAADSTS50011: The reply URL specified in the request does not matchAADSTS700016: Application with identifier was not foundinvalid_requestinvalid_responseSignature validation failedcertificate expiredclock skew too great
- Browser network tab shows a loop of
302redirects between your app and the identity provider. - Your app logs show lines like:
SAML assertion validation failed: certificate expired
OAuth callback rejected: redirect_uri mismatch
JWT validation error: token used before issued (nbf)
JWT validation error: token expired
TLS handshake failed when fetching IdP metadata
- Only SSO is broken; the app itself may still return
200 OKfor normal pages. - The issue affects all users, not one person or one browser.
Likely causes
| Cause | How common | Quick check |
|---|---|---|
| IdP outage or tenant-wide change | Very common | Open your IdP status page in a browser and check your admin audit log in the IdP dashboard |
| Redirect URL / ACS URL mismatch after a domain or app URL change | Very common | In your app admin: Authentication → SSO, copy the current callback/ACS URL and compare it to the IdP app's configured reply URL |
| SAML signing certificate or OIDC client secret expired/rotated | Common | In your app admin: Authentication → SSO, check certificate expiry or secret last rotated date |
| DNS or TLS problem on the SSO callback domain | Common | In a browser, open your app's SSO callback base domain and inspect the certificate padlock/details |
| Server clock drift causing token validation failure | Less common | In your server/dashboard metrics, compare system time to current UTC time |
Step-by-step diagnosis
-
Check whether your identity provider is having an incident.
- In your provider's dashboard, open the status page or service health page. Also open the admin audit log and look for changes this morning to the SSO application.
- What confirms the problem: a current incident, or an audit event showing the app was edited, disabled, certificates rotated, or reply URLs changed.
- Jump to: Fixes → IdP outage or tenant-wide change.
-
Confirm your app still points to the correct SSO callback URL.
- In your app admin dashboard, go to Authentication → SSO (or similar) and copy the ACS URL for SAML (Assertion Consumer Service, the URL that receives the login response) or Redirect/Callback URL for OIDC/OAuth.
- Then open your IdP app configuration and compare the configured Reply URL / Redirect URI character-for-character.
- What confirms the problem: any mismatch in domain, path, trailing slash,
httpvshttps, or old staging URL. - Jump to: Fixes → Redirect URL / ACS URL mismatch.
-
Check whether a certificate or client secret expired today.
- In your app admin dashboard, go to Authentication → SSO and look for the SAML signing certificate expiry date or OIDC client secret details. If your app stores IdP metadata by URL, click Refresh metadata if available.
- If you have CLI/server access, search logs for expiry errors:
grep -Ei "certificate expired|signature validation failed|client secret|invalid_client" /var/log/* 2>/dev/null | tail -n 50
- What confirms the problem: expiry date is today/yesterday, or logs show
certificate expired,invalid_client, orsignature validation failed. - Jump to: Fixes → SAML signing certificate or OIDC client secret expired/rotated.
- Rule out DNS or TLS trouble on your app domain.
- In a browser, open your normal app URL and click the padlock to inspect the certificate. Then verify the hostname is the same one used in the SSO callback URL.
- If you have terminal access, run:
curl -I https://your-app.example.com/
openssl s_client -connect your-app.example.com:443 -servername your-app.example.com </dev/null 2>/dev/null | openssl x509 -noout -dates -subject -issuer
- What confirms the problem: certificate expired, wrong hostname on the certificate, DNS now points somewhere else, or
curlfails with TLS/connection errors. - Jump to: Fixes → DNS or TLS problem on the SSO callback domain.
- Check server time if tokens are rejected as not-yet-valid or expired.
- In your hosting dashboard, open the instance/VM details and compare system time to current UTC. If you have shell access:
date -u
- What confirms the problem: server time is off by more than a minute or two, and logs mention
nbf,iat,exp, orclock skew. - Jump to: Fixes → Server clock drift.
- Run one clean end-to-end login test.
- Use a private/incognito browser window. Start at your app login page, click Sign in with SSO, and watch the final error page or URL.
- What confirms the problem: the final page usually names the failing side—IdP app not found, redirect mismatch, invalid signature, or callback unreachable.
- Jump to the matching fix section below.
Fixes
IdP outage or tenant-wide change
- If the status page shows an outage, the fix is usually to wait for the provider to restore service. During that time, enable a break-glass local admin account if your app supports one.
- If the admin audit log shows a change, revert it in the IdP app configuration:
- Re-enable the application.
- Restore the previous reply URL / ACS URL.
- Reassign users/groups if access assignments were removed.
- Restore the previous issuer/entity ID if it was edited.
- If your app uses metadata URL sync for SAML, refresh metadata in your app admin after the IdP-side rollback.
- Verify it worked: start a fresh incognito login and confirm you land inside the app instead of back at the login page.
Redirect URL / ACS URL mismatch
- In your app admin, copy the exact callback URL shown under Authentication → SSO.
- In your IdP application settings, replace the existing Reply URL / Redirect URI / ACS URL with that exact value.
- Common examples to compare carefully:
https://app.example.com/auth/sso/callback
https://app.example.com/auth/sso/callback/
https://www.example.com/auth/sso/callback
http://app.example.com/auth/sso/callback
- If you changed domains this morning, add the new production URL and remove old staging URLs after testing.
- Verify it worked: the next SSO attempt no longer shows
AADSTS50011,redirect_uri mismatch, orinvalid_request.
SAML signing certificate or OIDC client secret expired/rotated
- For SAML:
- In the IdP app, generate or activate the new signing certificate.
- In your app admin, either paste the new X.509 certificate or refresh from the IdP metadata URL.
- If your app accepts metadata XML upload, upload the fresh metadata file exported from the IdP.
- For OIDC/OAuth:
- In the IdP app, create a new client secret.
- Copy it immediately and paste it into your app under Authentication → SSO / OpenID Connect.
- Save, then remove the old secret only after a successful test.
- If you have environment-variable based config and server access, update and restart the app:
export OIDC_CLIENT_SECRET='new-secret-value'
sudo systemctl restart your-app
- Verify it worked: logs stop showing
invalid_client,signature validation failed, orcertificate expired, and a fresh SSO login succeeds.
DNS or TLS problem on the SSO callback domain
- In your DNS provider's dashboard (for example, DNS → Records), confirm the app hostname in the callback URL points to the correct load balancer, reverse proxy, or app server.
- If the record changed accidentally this morning, restore the previous value.
- Renew or replace the TLS certificate for the app hostname. If you use nginx and Certbot (Let's Encrypt client), a common renewal flow is:
sudo certbot renew
sudo nginx -t && sudo systemctl reload nginx
- If nginx is serving the wrong certificate, check the server block:
server {
listen 443 ssl;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
}
- Verify it worked:
curl -I https://your-app.example.com/returns a normal HTTP response and the browser shows a valid certificate for the correct hostname.
Server clock drift
- Sync the server time with NTP (Network Time Protocol, automatic time sync).
- On systemd-based Linux:
timedatectl status
sudo timedatectl set-ntp true
sudo systemctl restart systemd-timesyncd
- If you use chrony:
chronyc tracking
sudo systemctl restart chronyd
- After time is corrected, restart the app if it caches token validation settings:
sudo systemctl restart your-app
- Verify it worked:
date -umatches current UTC and logs no longer showtoken used before issued,nbf, orclock skew.
Prevention
- Monitor certificate and secret expiry before the morning surprise. Add calendar reminders and automated checks for SAML certs and OIDC secrets.
openssl x509 -in idp-signing-cert.pem -noout -enddate
- Keep the callback URL in one source of truth and test it in CI. Store the production base URL in config, then fail builds if the generated callback URL changes unexpectedly.
test "$(printf "%s" "$APP_BASE_URL/auth/sso/callback")" = "https://app.example.com/auth/sso/callback"
- Alert on SSO failure spikes. In your log tool, create an alert for terms like
redirect_uri mismatch,invalid_client,signature validation failed, andAADSTS50011crossing a threshold in 5 minutes.
count(error where message contains "signature validation failed" or message contains "redirect_uri mismatch") > 5 in 5m
- Enable metadata refresh or document the manual rotation runbook. If your app supports metadata URL sync for SAML, use it. If not, store the exact export/import steps in your internal admin notes.
- Monitor DNS and TLS on the app hostname used by SSO. Add an external uptime check that validates both HTTP
200/302and certificate expiry forapp.example.com.
curl -fsS -o /dev/null -w "%{http_code}\n" https://app.example.com/
- Keep one non-SSO emergency admin account and test it monthly. This avoids being locked out of your own app while you repair SSO settings.
This article was written by an AI system and published pending human review. Verify anything you intend to act on.
Have a project in mind?
Get an instant AI price estimate for it, or talk directly to our team.
One email a month on what we learn building with AI