Jenkins cannot write config xml

hello!

i have recently upgraded jenkins from version 2.462.3 to 2.516.2 and have ran into an issue with jenkins being seemingly unable to write certain configuration options to the local storage. the relevant stacktrace is a the bottom of this post. what i have tried:

  • all plugins are disabled
  • removing all the jenkins config files and forcing jenkins to recreate them

this upgrade required moving to Java 17 (17.0.2 openjdk) and upgrading tomcat to version 10. i am also using httpd and tanuki wrapper version 3.6.3. some of the configuration options appear to have been written such as the LDAP security config and the system message, but other things like the environment variables and the built-in node config dont persist. this causes all of the config to be dropped on a restart of the jenkins service.

Jenkins setup:

Jenkins: 2.516.2
OS: Linux - 3.10.0-1160.138.1.el7.x86_64
Java: 17.0.2 - Red Hat, Inc. (OpenJDK 64-Bit Server VM)
---
ace-editor:1.1
ant:518.v8d8dc7945eca_
antisamy-markup-formatter:173.v680e3a_b_69ff3
apache-httpcomponents-client-4-api:4.5.14-269.vfa_2321039a_83
apache-httpcomponents-client-5-api:5.5-170.v023de017ccd7
artifactory:4.0.8
asm-api:9.8-163.vb_2a_96d3f9c3c
atlassian-jira-software-cloud:2.0.15
audit2db:0.5
authentication-tokens:1.144.v5ff4a_5ec5c33
blueocean:1.27.21
blueocean-autofavorite:1.2.5
blueocean-bitbucket-pipeline:1.27.21
blueocean-commons:1.27.21
blueocean-config:1.27.21
blueocean-core-js:1.27.21
blueocean-dashboard:1.27.21
blueocean-display-url:2.4.4
blueocean-events:1.27.21
blueocean-executor-info:1.27.21
blueocean-git-pipeline:1.27.21
blueocean-github-pipeline:1.27.21
blueocean-i18n:1.27.21
blueocean-jira:1.27.21
blueocean-jwt:1.27.21
blueocean-personalization:1.27.21
blueocean-pipeline-api-impl:1.27.21
blueocean-pipeline-editor:1.27.21
blueocean-pipeline-scm-api:1.27.21
blueocean-rest:1.27.21
blueocean-rest-impl:1.27.21
blueocean-web:1.27.21
bootstrap4-api:4.6.0-6
bootstrap5-api:5.3.8-890.v1c5cf4fa_178e
bouncycastle-api:2.30.1.82-277.v70ca_0b_877184
branch-api:2.1255.v2f5fe203584a_
build-monitor-plugin:1.14-985.v7b_f37b_3d0b_f5
build-name-setter:2.5.1
build-token-root:151.va_e52fe3215fc
build-token-trigger:1.0.0
byte-buddy-api:1.17.7-181.ve4f4387cb_a_86
caffeine-api:3.2.2-178.v353b_8428ed56
checks-api:373.vfe7645102093
claim:617.v149399f86b_de
cloudbees-bitbucket-branch-source:937.1.0
cloudbees-credentials:3.3
cloudbees-folder:6.1053.vd62fb_b_f7367b_
command-launcher:123.v37cfdc92ef67
commons-collections4-api:4.5.0-8.va_d5448ef9011
commons-compress-api:1.28.0-1
commons-lang3-api:3.19.0-104.v12125f33a_255
commons-text-api:1.14.0-194.v804a_dc3a_1b_d8
conditional-buildstep:1.5.0
config-file-provider:1002.v93e06b_792d44
copyartifact:770.va_6c69e063442
credentials:1447.v4cb_b_539b_5321
credentials-binding:702.vfe613e537e88
cucumber-reports:5.10.0
data-tables-api:2.3.4-1400.vb_1e3e3c4dfc8
database:274.vea_2e859b_2661
disk-usage:1.3
display-url-api:2.217.va_6b_de84cc74b_
docker-build-publish:1.4.0
docker-commons:457.v0f62a_94f11a_3
docker-slaves:1.0.7
docker-workflow:621.va_73f881d9232
durable-task:605.v9a_b_9040c9970
echarts-api:6.0.0-1146.v5c8f3b_8f0573
eddsa-api:0.3.0.1-19.vc432d923e5ee
email-ext:1925.v1598902b_58dd
environment-script:100.v3a_f1a_6a_b_7549
extended-choice-parameter:388.ve7b_d0b_920e10
external-monitor-job:223.vb_fddcf42c9b_3
favorite:2.253.v9b_413168133b_
flatpickr-api:4.6.13-18.vcf5f6a_5b_8468
font-awesome-api:7.0.1-859.v128d3a_efb_6e5
git:5.7.0
git-client:6.4.0
git-server:137.ve0060b_432302
github:1.45.0
github-api:1.330-492.v3941a_032db_2a_
github-branch-source:1871.v50ffb_786515e
global-build-stats:347.v32a_eb_0493c4f
gradle:2.16.1149.v711b_998b_0532
groovy:497.v7b_061a_a_de65d
gson-api:2.13.2-173.va_a_092315913c
handlebars:3.0.8
handy-uri-templates-2-api:2.1.8-36.v85e4cb_234a_13
hidden-parameter:494.v9d2513a_9994d
htmlpublisher:427
http_request:1.20
instance-identity:203.v15e81a_1b_7a_38
ionicons-api:94.vcc3065403257
ivy:582.v35fb_da_0312f7
jackson2-api:2.20.0-411.v6ef8fdee4fe9
jakarta-activation-api:2.1.3-2
jakarta-mail-api:2.1.3-3
javadoc:354.vee1a_660b_4990
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
jenkins-design-language:1.27.21
jersey2-api:2.47-165.ve7809a_3e87e0
jira:3.19
jjwt-api:0.11.5-120.v0268cf544b_89
job-dsl:1.93
job-import-plugin:122.v35289550f1e6
joda-time-api:2.14.0-149.v1c3ce991d1b_9
jquery:1.12.4-3
jquery-detached:1.2.1
jquery3-api:3.7.1-594.vb_3864f326cf0
jsch:0.2.16-95.v3eecb_55fa_b_78
json-api:20250517-173.v596efb_962a_31
json-path-api:2.9.0-190.veefca_05d5477
jsoup:1.21.2-66.v6ea_38164b_8a_2
junit:1361.vfed194a_de34a_
ldap:793.v754d6b_41b_ea_4
lockable-resources:1412.v3f305a_fb_a_117
mailer:522.va_995fa_cfb_8b_d
mapdb-api:1.0.9-44.va_1e1310c9118
mask-passwords:204.v24d863065180
matrix-auth:3.2.8
matrix-project:858.vb_b_eb_9a_7ea_99e
maven-plugin:3.27
mercurial:1323.ve69d2a_db_8a_b_d
metrics:4.2.37-487.v7d6048d8733c
mina-sshd-api-common:2.16.0-167.va_269f38cc024
mina-sshd-api-core:2.16.0-167.va_269f38cc024
momentjs:1.1.1
multi-branch-project-plugin:0.7
nodejs:1.6.5
okhttp-api:4.12.0-195.vc02552c04ffd
opentelemetry-api:1.49.0.82.vf56234f0d9c1
oss-symbols-api:392.v27a_482d90083
pagerduty:0.7.1
pam-auth:1.12
parameterized-trigger:873.v8b_e37dd8418f
pipeline-build-step:571.v08a_fffd4b_0ce
pipeline-graph-analysis:245.v88f03631a_b_21
pipeline-groovy-lib:766.v2b_e08c2e6ff2
pipeline-input-step:534.v352f0a_e98918
pipeline-milestone-step:138.v78ca_76831a_43
pipeline-model-api:2.2273.v643f36ed9e94
pipeline-model-declarative-agent:1.1.1
pipeline-model-definition:2.2273.v643f36ed9e94
pipeline-model-extensions:2.2273.v643f36ed9e94
pipeline-rest-api:2.38
pipeline-stage-step:322.vecffa_99f371c
pipeline-stage-tags-metadata:2.2273.v643f36ed9e94
pipeline-stage-view:2.38
pipeline-utility-steps:2.20.0
plain-credentials:199.v9f8e1f741799
plugin-util-api:6.1167.v022176c7e0ca_
popper-api:1.16.1-3
popper2-api:2.11.6-5
pubsub-light:1.19
radiatorviewplugin:1.29
rebuild:338.va_0a_b_50e29397
release:2.19
resource-disposer:0.25
run-condition:243.v3c3f94e46a_8b_
scm-api:711.va_e7ca_4d96f53
scm-sync-configuration:0.0.10
script-security:1378.vf25626395f49
seleniumhtmlreport:1.1
slack:795.v4b_9705b_e6d47
snakeyaml-api:2.3-125.v4d77857a_b_402
sqlplus-script-runner:3.0.1
sse-gateway:1.28
ssh-agent:386.v36cc0c7582f0
ssh-credentials:361.vb_f6760818e8c
ssh-slaves:3.1071.v0d059c7b_c555
sshd:3.374.v19b_d59ce6610
structs:353.v261ea_40a_80fb_
subversion:1292.ve8cf25770ee3
terraform:1.0.10
timestamper:1.30
token-macro:477.vd4f0dc3cb_cf1
trilead-api:2.209.v0e69b_c43c245
variant:70.va_d9f17f859e0
versionnumber:234.v315d3b_3cb_fb_5
windows-slaves:1.8.1
workflow-aggregator:608.v67378e9d3db_1
workflow-api:1384.vdc05a_48f535f
workflow-basic-steps:1098.v808b_fd7f8cf4
workflow-cps:4209.v83c4e257f1e9
workflow-cps-global-lib:615.vb_b_0664a_b_19f3
workflow-durable-task-step:1464.v2d3f5c68f84c
workflow-job:1549.vc8d7f497b_22f
workflow-multibranch:821.vc3b_4ea_780798
workflow-scm-step:452.vdf1ca_c8d3a_87
workflow-step-api:710.v3e456cc85233
workflow-support:991.v66c18437d509
ws-cleanup:0.49

catalina.out snippet after saving in the GUI

INFO   | jvm 1    | 2025/10/17 13:02:05 | WARNING: null
INFO   | jvm 1    | 2025/10/17 13:02:05 | java.io.IOException: java.lang.RuntimeException: Failed to serialize jenkins.model.Jenkins#globalNodeProperties for class hudson.model.Hudson
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.XmlFile.write(XmlFile.java:223)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at jenkins.model.Jenkins.save(Jenkins.java:3615)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.BulkChange.commit(BulkChange.java:98)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at jenkins.model.Jenkins.doConfigSubmit(Jenkins.java:4061)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:484)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:497)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:218)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.SelectionInterceptedFunction$Adapter.invoke(SelectionInterceptedFunction.java:37)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.verb.HttpVerbInterceptor.invoke(HttpVerbInterceptor.java:48)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.SelectionInterceptedFunction.bindAndInvoke(SelectionInterceptedFunction.java:26)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:140)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.MetaClass$12.doDispatch(MetaClass.java:686)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:61)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:800)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:938)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:871)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:938)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.MetaClass$10.dispatch(MetaClass.java:590)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:800)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:938)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:721)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.Stapler.service(Stapler.java:253)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:204)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at jenkins.util.HttpServletFilter$1.doFilter(HttpServletFilter.java:77)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:201)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:207)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at jenkins.ErrorAttributeFilter.doFilter(ErrorAttributeFilter.java:29)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:154)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.security.ChainedServletFilter2$1.doFilter(ChainedServletFilter2.java:94)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.security.ChainedServletFilter2.doFilter(ChainedServletFilter2.java:111)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:173)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.UncaughtExceptionFilter.doFilter(UncaughtExceptionFilter.java:26)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:86)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:31)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at jenkins.security.SuspiciousRequestFilter.doFilter(SuspiciousRequestFilter.java:38)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:598)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:666)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1776)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:975)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:493)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at java.base/java.lang.Thread.run(Thread.java:833)
INFO   | jvm 1    | 2025/10/17 13:02:05 | Caused by: java.lang.RuntimeException: Failed to serialize jenkins.model.Jenkins#globalNodeProperties for class hudson.model.Hudson
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:276)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:243)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:174)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:228)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:165)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:44)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:83)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.XStream.marshal(XStream.java:1307)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.XStream.marshal(XStream.java:1296)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.XStream.toXML(XStream.java:1269)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.XmlFile.write(XmlFile.java:216)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	... 74 more
INFO   | jvm 1    | 2025/10/17 13:02:05 | Caused by: java.lang.RuntimeException: Failed to serialize hudson.slaves.EnvironmentVariablesNodeProperty#envVars for class hudson.slaves.EnvironmentVariablesNodeProperty
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:276)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:243)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:174)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:228)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:165)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:44)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:87)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeBareItem(AbstractCollectionConverter.java:94)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:66)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.DescribableList$ConverterImpl.marshal(DescribableList.java:294)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:83)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:285)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:272)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	... 87 more
INFO   | jvm 1    | 2025/10/17 13:02:05 | Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field transient java.util.Set java.util.AbstractMap.keySet accessible: module java.base does not "opens java.util" to unnamed module @79c38e36
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.converters.reflection.FieldDictionary.buildDictionaryEntryForClass(FieldDictionary.java:187)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.converters.reflection.FieldDictionary.buildMap(FieldDictionary.java:153)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.converters.reflection.FieldDictionary.fieldsFor(FieldDictionary.java:81)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:167)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:208)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:165)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:83)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:285)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:272)
INFO   | jvm 1    | 2025/10/17 13:02:05 | 	... 103 more

can someone point me in the right direction?

Due to the module system that is enforced with java 17 you must open some modules.
You will need to add the following to the java options when starting tomcat:

--add-opens java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED

The better option is probably to say goodbye to tomcat and use the built-in jetty by running jenkins with java <java_opt> -jar jenkins.war <jenkins_opts>. Those options I mentioned are not required as they are maintained in the MANIFEST.MF in the war file.

can confirm adding those options to the tanuki wrapper solved my issue. thank you!