Certificate Based Mutual Authentication (mTLS) is failing with errorIssue <!-- /*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: ; } } Integrations using Mutual TLS (mTLS) fails with one or more of following errors: SSLHandshakeException Peer Not AuthenticatedSocket Closed Key Error Signatures: SSLHandshakeException path: javax.net.ssl|ERROR|...|TransportContext.java:375| Fatal (CERTIFICATE_UNKNOWN): PKIX path building failed: unable to find valid certification path to requested targetSocketException: (java.net.SocketException) caught when processing request: Socket is closedDBKeyStoreSocketFactory DEBUG: Unable to collect telemetry data for certificate. Exception: peer not authenticatedHTTPClient WARNING: Request not sent to uri=[URI] : java.net.SocketException: Socket is closed Symptoms<!-- /*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: ; } } Integration fails immediately — no request reaches the endpointOperation Flow / localhost log shows: Request not sent to [URI] : java.net.SocketException: Socket is closedDBKeyStoreSocketFactory DEBUG: Unable to collect telemetry data for certificate. Exception: peer not authenticated Wrapper / localhost log shows SSLHandshakeException: javax.net.ssl.SSLHandshakeException: PKIX path building failedsun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested targetFatal (CERTIFICATE_UNKNOWN) in TransportContext Requests using cURL and Postman from the application server succeed — the issue is specific to ServiceNow's HTTP clientThe issue may appear suddenly with no code changes — caused by a silent server-side certificate chain change at the endpointExternal system reports authentication failure when calling ServiceNow instanceServiceNow logs show SSLPeerUnverifiedException or client certificate rejectionMutual authentication profile is configured on the Outbound REST Message but the calling client's CA certificate is not trusted in [sys_certificate]javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated in the localhost logs (see KB0827182) Facts<!-- /*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: ; } } Why cURL and Postman succeed but ServiceNow fails? cURL and Postman by default skip server certificate chain validation (-k / insecure mode) unless explicitly configured otherwise. ServiceNow's Java-based HTTP client performs strict PKIX path validation and will reject any server certificate whose complete chain (root CA + all intermediates) is not trusted in [sys_certificate]. These are fundamentally different trust models — a successful cURL test does not confirm TLS trust. Why the error surfaces as "Socket is closed"? The SSLHandshakeException triggers a Fatal TLS alert. The JVM closes the socket immediately after sending the alert, so the higher-level ServiceNow class (AbstractHttpOperation) catches the resulting SocketException rather than the underlying SSL exception. The "peer not authenticated" entry from DBKeyStoreSocketFactory and the "Socket is closed" entry always appear together — both confirm the root cause is TLS trust failure, not a network issue. Private CAs are not in ServiceNow's default trust store Public CAs (Let's Encrypt, DigiCert, etc.) are included in ServiceNow's default Java trust store. Endpoints using a private or internal CA (e.g. an enterprise PKI with a self-signed root) are NOT trusted by default. The root and any intermediate certificates from such a private CA must be manually imported into [sys_certificate] as Type = Trust Store Certificate. 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: ; } } All versions Cause<!-- /*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: ; } } The [sys_certificate] table was missing the root CA and/or intermediate CA certificate(s) needed to complete the TLS trust chain for the endpoint. Java's PKIX path builder cannot validate the server's certificate without the full chain present locally, causing SSLHandshakeException. The socket closes immediately, surfacing as "Socket is closed" in the Flow Engine. Contributing factors: Endpoint presents an incomplete certificate chain (leaf only, no intermediate)The required CA certificate was never imported into [sys_certificate] (common with private / enterprise CAs)A silent server-side certificate chain change at the endpoint Resolution<!-- /*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: ; } } Step 1 - Verify the certificate chain presented by the endpoint Run the following command from an application server node. The -showcerts flag dumps the full chain as sent by the server: # Force SNI explicitly and check output openssl s_client -showcerts -connect <hostname>:<port> -servername <hostname> 2>/dev/null | grep -v "BEGIN CERTIFICATE" | grep -v "END CERTIFICATE" | grep -v "^[A-Za-z0-9+/=]*$" Review the Certificate chain output. A complete chain looks like this (example from a well-configured endpoint): Certificate chain 0 s:/CN=<hostname> <- leaf cert i:/CN=<Intermediate-CA> 1 s:/CN=<Intermediate-CA> <- intermediate cert i:/CN=<Root-CA> 2 s:/CN=<Root-CA> <- root cert (self-signed) i:/CN=<Root-CA> If only index 0 is present (leaf cert only), the endpoint is presenting an incomplete chain. Engage the endpoint owner to configure their server to send the full chain. If the full chain is present, proceed to Step 2. Step 2 — Validate trust store coverage in ServiceNow Navigate to System Security > Certificates (sys_certificate.list). Check whether the issuer CA(s) from the openssl output exist as Trust Store Certificate records with valid attachments. For each missing CA certificate: Set Type = Trust Store CertificateImport root CA first, then intermediate CA(s) — order matters for chain validationConfirm each record has a DER/PEM file attachment (a record with no attachment will fail silently) Refer to the ServiceNow documentation requirement - "Before importing your domain's primary certificate, any root or intermediate certificates should be imported first." Step 3 — Re-run the integration to validate Trigger the failing outbound integrationConfirm SSLHandshakeException and "Socket is closed" errors no longer appear in the wrapper/localhost logsConfirm the Operation Flow execution log shows a successful HTTP response from the endpoint If the above steps do not resolve the issue, enable SSL Debug Logging in the app node (Note: if your instance is hosted in ServiceNow cloud, please reach out to support for assistance) Add the JVM parameter to wrapper.conf in one of the application nodes, then restart that node. // JVM parameter to add to wrapper.conf: -Djavax.net.debug=ssl:handshake:verbose After reproducing the issue, collect the wrapper log and localhost log from that node. Look for the Consuming server Certificate handshake message block — it will show whether the server sent one certificate (leaf only) or a full chain. // In the debug output, look for this block: javax.net.ssl|DEBUG|...|CertificateMessage.java:366| Consuming server Certificate handshake message "Certificates": [ "certificate" : { "version":"v3", "issuer":"CN=<issuer>", ... }, <- leaf cert "certificate" : { "version":"v3", "issuer":"CN=<root>", ... }, <- intermediate (should be present) ... ] // If only one certificate entry is present, then the certificate chain is incomplete Related Links<!-- /*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: ; } } Configure mutual authenticationEnforce Certificate TrustKB1648222 - Implementation Guide: How to Set Up Outbound Mutual AuthenticationKB0993615 - How to configure inbound Certificate Based Authentication (mutual authentication) in ServiceNowKB0827182 - Outbound REST calls failing with javax.net.ssl.SSLPeerUnverifiedException: peer not authenticatedKB1184864 - SEVERE ERROR: Unable to load certificate code-signing-key_xxxxxxxxxx