Katalon Object Manager throws SSLHandshake Exception on mTLS API requests

Hey everyone, I’m really hitting a wall here. My team just moved our APIs to require mutual TLS (mTLS), which means I need to send a client certificate along with my requests.

I’ve been using the Object Manager (Object Repository) in Katalon Studio to build out our API test suite. Every time I hit the “Send” button on my secure request, the console just spits out a massive javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure or ValidatorException: PKIX path building failed.

Here is what I’ve tried so far:

  • I added the certificate to my Windows Certificate Manager thinking Katalon would just grab it automatically. It didn’t.

  • I tried adding it under Project > Settings > Network but that only seems to let me configure a proxy, not an SSL/TLS client certificate keystore.

  • I tried changing the URL from https to http just to see if I could bypass it for local testing, but our staging server strictly rejects non-HTTPS traffic.

I’m completely stuck. How do I actually tell Katalon’s Object Manager to use our team’s .p12 / .pfx client certificate so I can test these endpoints without writing a thousand lines of custom Java code for every single request?

The Diagnosis

The root cause of the SSLHandshakeException is that Katalon Studio’s built-in HTTP client (which powers the Object Repository UI) utilizes the default Java Virtual Machine (JVM) truststore and keystore. When an endpoint demands mutual authentication, the server requests a client certificate. Because Katalon’s default network execution profile is unaware of your custom client certificate (.p12, .pfx, or .jks), the TLS handshake fails immediately.

To solve this globally and seamlessly for both the Object Manager UI and test executions, we must configure Katalon’s execution properties to initialize the JVM with your specific keystore parameters.

The Solution: Global JVM Arguments

The most scalable, industry-standard approach doesn’t require modifying individual Object Repository objects. Instead, you inject the keystore configuration directly into Katalon’s execution profile via Project Settings.

  1. Open your project in Katalon Studio.

  2. Navigate to Project > Settings > Execution > Default > Web Service (or External depending on your version’s execution paths).

  3. Add the following JVM arguments to the execution parameters:

Plaintext

-Djavax.net.ssl.keyStore=C:/path/to/your/certificate.p12
-Djavax.net.ssl.keyStorePassword=your_keystore_password
-Djavax.net.ssl.keyStoreType=PKCS12

Note: If you are using a .jks file instead of .p12, change the keyStoreType value to JKS.

Custom Keyword Helper (For Dynamic/Multi-Certificate Environments)

If your framework requires switching between different client certificates dynamically during a test run (which cannot be handled by static JVM arguments), you must override the engine’s default system properties programmatically before the request is invoked.

Below is a robust Custom Keyword to handle this programmatically.

Groovy

package com.architecture.tls

import com.kms.katalon.core.annotation.Keyword
import com.kms.katalon.core.util.KeywordUtil

public class SSLContextHelper {

    /**
     * Dynamically sets the SSL Client Certificate for mTLS handshakes
     * @param keystorePath Absolute path to the .p12 or .jks file
     * @param keystorePassword The password for the keystore
     * @param keystoreType Default is "PKCS12", use "JKS" if applicable
     */
    @Keyword
    public static void setClientCertificate(String keystorePath, String keystorePassword, String keystoreType = "PKCS12") {
        try {
            System.setProperty("javax.net.ssl.keyStore", keystorePath)
            System.setProperty("javax.net.ssl.keyStorePassword", keystorePassword)
            System.setProperty("javax.net.ssl.keyStoreType", keystoreType)
            
            KeywordUtil.logInfo("Successfully loaded mTLS client certificate profile: " + keystorePath)
        } catch (Exception e) {
            KeywordUtil.markFailed("Failed to set SSL System Properties: " + e.getMessage())
        }
    }
}

How to use it in a Test Case:

Groovy

// Call this at the very beginning of your test script before hitting the Object Repository request
CustomKeywords.'com.architecture.tls.SSLContextHelper.setClientCertificate'('C:/certs/client.p12', 'SecurePass123!')

// Now send your object manager request safely
WS.sendRequest(findTestObject('Object Repository/Secure_API_Endpoint'))

Likely cause

The handshake failure usually means the server requested mutual authentication, but Katalon did not present a valid client certificate from the configured keystore. In some cases, certificate format or JVM truststore issues can also cause handshake problems, especially if the chain is incomplete or the keystore type is incompatible.

Practical takeaway

The clean fix is to configure the client certificate in Katalon’s API project settings using the full keystore path and password, ideally with a .p12 file. If the endpoint also has trust-chain problems, then the server/root certificate may need to be imported into the Java truststore used by Katalon.