Issue connecting Windows nodes to Linux controller after SSL rotation

After receiving a new SSL cert (in JKS format), I can successfully get the controller to work with SSL, however, the Windows build nodes will no longer connect with error:

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Being new to Linux (Ubuntu) and SSL, I’m at a loss. I was able to get the controller and nodes set up initially with SSL, however, the cert expired and we need to rotate it.

Thanks!
Andy

Jenkins setup:

Jenkins: 2.492.2
OS: Linux - 5.15.0-134-generic
Java: 17.0.14 - Ubuntu (OpenJDK 64-Bit Server VM)

active-directory:2.39
ant:513.vde9e7b_a_0da_0f
antisamy-markup-formatter:173.v680e3a_b_69ff3
apache-httpcomponents-client-4-api:4.5.14-269.vfa_2321039a_83
asm-api:9.7.1-97.v4cc844130d97
authentication-tokens:1.131.v7199556c3004
badge:2.7
bootstrap5-api:5.3.3-2
bouncycastle-api:2.30.1.80-256.vf98926042a_9b_
branch-api:2.1214.v3f652804588d
build-failure-analyzer:2.5.4
build-timeout:1.36
build-with-parameters:76.v9382db_f78962
caffeine-api:3.2.0-161.v691ef352cee1
checks-api:367.v18b_7f530e54a_
cloudbees-folder:6.985.va_f1635030cc5
command-launcher:118.v72741845c17a_
commons-lang3-api:3.17.0-84.vb_b_938040b_078
commons-text-api:1.13.0-153.v91dcd89e2a_22
conditional-buildstep:1.5.0
copyartifact:765.v0357cc6e6eb_3
credentials:1408.va_622a_b_f5b_1b_1
credentials-binding:687.v619cb_15e923f
cygpath:1.5
dark-theme:524.vd675b_22b_30cb_
disk-usage:1.3
display-url-api:2.209.v582ed814ff2f
docker-commons:451.vd12c371eeeb_3
docker-workflow:611.v16e84da_6d3ff
durable-task:587.v84b_877235b_45
echarts-api:5.6.0-2
eddsa-api:0.3.0-13.v7cb_69ed68f00
editable-choice:71.v02a291ebbe45
email-ext:1876.v28d8d38315b_d
emoji-symbols-api:16.0-26.v9818ff7423f0
envinject:2.926.v69c9b_3896a_96
envinject-api:1.235.va_14c74f8f487
extensible-choice-parameter:237.v51568f37b_78e
external-monitor-job:221.v35059272565b_
fail-the-build-plugin:5.v153b_2c826ef0
favorite:2.225.v68765b_b_a_1fa_3
file-parameters:358.v9ed4456a_169a_
font-awesome-api:6.7.2-1
git:5.7.0
git-client:6.1.2
git-parameter:0.11.0
git-tag-message:1.7.1
github:1.42.0
github-api:1.321-478.vc9ce627ce001
github-branch-source:1810.v913311241fa_9
gradle:2.14.1
groovy-postbuild:272.v52a_03efb_8653
gson-api:2.12.1-113.v347686d6729f
hidden-parameter:414.vfe0a_8b_052546
htmlpublisher:424.va_e57f1253461
instance-identity:203.v15e81a_1b_7a_38
ionicons-api:82.v0597178874e1
jackson2-api:2.18.3-402.v74c4eb_f122b_2
jakarta-activation-api:2.1.3-2
jakarta-mail-api:2.1.3-2
javadoc:310.v032f3f16b_0f8
javax-activation-api:1.2.0-8
javax-mail-api:1.6.2-11
jaxb:2.3.9-133.vb_ec76a_73f706
jdk-tool:83.v417146707a_3d
jfrog:1.5.8
jjwt-api:0.11.5-120.v0268cf544b_89
job-import-plugin:122.v35289550f1e6
jobConfigHistory:1305.vf20a_356586b_8
joda-time-api:2.13.1-115.va_6b_5f8efb_1d8
jquery3-api:3.7.1-3
jsch:0.2.16-95.v3eecb_55fa_b_78
json-api:20250107-125.v28b_a_ffa_eb_f01
json-path-api:2.9.0-148.v22a_7ffe323ce
junit:1317.v5b_35d792b_06a_
last-changes:2.8.0
ldap:776.vddf3e325103b_
leastload:62.vfa_8830902733
log-parser:2.3.7
mail-watcher-plugin:1.20
mailer:489.vd4b_25144138f
mapdb-api:1.0.9-44.va_1e1310c9118
matrix-auth:3.2.4
matrix-project:845.vffd7fa_f27555
maven-plugin:3.25
metrics:4.2.21-464.vc9fa_a_0d6265d
mina-sshd-api-common:2.14.0-143.v2b_362fc39576
mina-sshd-api-core:2.14.0-143.v2b_362fc39576
next-build-number:66.v4b_4762172d53
nodelabelparameter:759.vb_b_e95db_f3251
okhttp-api:4.11.0-183.va_87fc7a_89810
oss-symbols-api:308.v0c48656b_15c1
pam-auth:1.12
parameterized-trigger:840.v3c7d4a_a_5e6c7
pipeline-build-step:557.v95d96f77b_2b_8
pipeline-github-lib:65.v203688e7727e
pipeline-graph-analysis:231.v56354571a_da_0
pipeline-graph-view:423.v765c49ca_da_3f
pipeline-groovy-lib:752.vdddedf804e72
pipeline-input-step:517.vf8e782ee645c
pipeline-milestone-step:127.vb_52887ca_3b_6d
pipeline-model-api:2.2247.va_423189a_7dff
pipeline-model-definition:2.2247.va_423189a_7dff
pipeline-model-extensions:2.2247.va_423189a_7dff
pipeline-rest-api:2.37
pipeline-stage-step:322.vecffa_99f371c
pipeline-stage-tags-metadata:2.2247.va_423189a_7dff
pipeline-stage-view:2.37
plain-credentials:183.va_de8f1dd5a_2b_
plugin-util-api:6.0.0
powershell:2.3
rebuild:338.va_0a_b_50e29397
resource-disposer:0.25
run-condition:243.v3c3f94e46a_8b_
scm-api:704.v3ce5c542825a_
script-security:1373.vb_b_4a_a_c26fa_00
show-build-parameters:1.0
agent-utilization-plugin:1.8
snakeyaml-api:2.3-123.v13484c65210a_
ssh-credentials:355.v9b_e5b_cde5003
ssh-slaves:3.1031.v72c6b_883b_869
sshd:3.353.v2b_d33c46e970
structs:343.vdcf37b_a_c81d5
subversion:1287.vd2d507146906
theme-manager:278.v2e3c063e42cc
throttle-concurrents:2.16
timestamper:1.28
token-macro:444.v52de7e9c573d
trilead-api:2.192.vc50a_d147e369
variant:70.va_d9f17f859e0
veracode-scan:24.2.23.0
versionnumber:234.v315d3b_3cb_fb_5
windows-cloud:1.0.1
workflow-aggregator:600.vb_57cdd26fdd7
workflow-api:1363.v03f731255494
workflow-basic-steps:1079.vce64b_a_929c5a_
workflow-cps:4043.va_fb_de6a_a_8b_f5
workflow-durable-task-step:1405.v1fcd4a_d00096
workflow-job:1505.vea_4b_20a_4a_495
workflow-multibranch:803.v08103b_87c280
workflow-scm-step:437.v05a_f66b_e5ef8
workflow-step-api:700.v6e45cb_a_5a_a_21
workflow-support:961.v51869f7b_d409
ws-cleanup:0.48

A typical error with ssl is to not include the intermediate certificates in the keystore. Browsers are smart and often find a way to create the chain from the hosts certificate to the root certificate but tools like curl or java programs (here your java agent process) usually don’t find that chain.
So what does this mean.
When you sign a certificate it is common that the signing doesn’t happen with a root certificate but an intermediate certificate. The chain is website → intermediate cert → root cert.
curl or java only trust the root cert, so for them to be able to check if they can trust the website they need to know the intermediate certificate.
It is then the job of the website (Jenkins in your case) to provide the intermediate certificate in it’s answer when the ssl connection gets initialized.

To validate that your jenkins is properly returning the intermediate certificate run from a linux machine the following
openssl s_client -connect <hostname>:443
Assuming that the root cert is trusted on that machine you will get something like this as output at the beginning

depth=2 C = xx, L = xxx, O = xxx, CN = <root cert name>
verify return:1
depth=1 C = xx, L = xxx, O = xxx, CN = <intermediate cert name>
verify return:1
depth=0 C = xx, O = xx, OU = xxx, CN = <hostname>
verify return:1
---
Certificate chain
 0 s:/C=xx/O=xxx/OU=xxx/CN=<hostname>
   i:/C=xx/L=xx/O=xxx/CN=<intermediate cert name>
 1 s:/C=xx/L=xxx/O=xxx/CN=<intermediate cert name>
   i:/C=xx/L=xxx/O=xxx/CN=<root cert name>
 2 s:/C=xx/L=xxx/O=xxx/CN=<root cert name>
   i:/C=xx/L=xxx/O=xxx/CN=<root cert name>

The exact output depends a bit what is included in your setup, e.g. OU might not be there

If openssl is not able to find a chain to a trusted root cert you will see something like this in the output, e.g. when the intermediate is missing

depth=0 C = xx, L = xxx, O = xxx, CN = <intermediate cert name>
verify error:num=19:self-signed certificate in certificate chain

You will need to add the intermediate cert in the jks keystore then.

Of course the problem can also be something else. But that is then hard to analyze without having access to the environment