WebLogic enableHSTS — tested behaviour on 12.2.1.4 and 14.1.2.0

Live-tested on real EC2 lab hosts (curl against each listener before/after each change), not just read from docs. Both WLS versions behave the same.

Result

-Dweblogic.http.headers.enableHSTS=true on the Admin Server's JAVA_OPTIONS makes it send Strict-Transport-Security on every HTTPS response from that server — the Administration Console, other apps on the same server, the regular SSL listener, and the administration port once enabled. It does not send the header over plain HTTP, and browsers wouldn't honour it there anyway.

WLS versionListenerenableHSTSHeader sent?Value
12.2.1.4SSL (7002)falseNo—
12.2.1.4SSL (7002)trueYesmax-age=31536000; includeSubDomains; preload
12.2.1.4admin porttrueYesmax-age=31536000; includeSubDomains; preload
12.2.1.4HTTP (7001)trueNo—
14.1.2.0SSL (7002)falseNo—
14.1.2.0SSL (7002)trueYesmax-age=31536000; includeSubDomains; preload
14.1.2.0SSL (7002), customtrueYesmax-age=300 (includeSubDomains/preload correctly dropped when the matching flags are set false)
14.1.2.0admin porttrueYesmax-age=31536000; includeSubDomains; preload
14.1.2.0HTTP (7001)trueNo—

Custom values tested: -Dweblogic.http.headers.hsts.maxage=300 -Dweblogic.http.headers.hsts.includesubdomains=false -Dweblogic.http.headers.hsts.preload=false on 14.1.2.0 — the header value changed to match exactly.

Two things a lab domain needs before this is even testable

A freshly-created WLS domain (via WLST readTemplate/writeDomain on the base wls.jar template) does NOT have SSL enabled by default, on either version — confirmed via WLST (cmo.isEnabled() on /Servers/AdminServer/SSL/AdminServer returns False), even though ListenPort already defaults to 7002. A comment claiming SSL is 'enabled automatically' for a Development-mode domain was wrong for this template. Enable it with:

edit(); startEdit()
cd('/Servers/AdminServer/SSL/AdminServer')
cmo.setEnabled(true)
cmo.setListenPort(7002)
save(); activate()
# then restart the server

The administration port is also off by default. Enable it with (domain-level, not server-level):

edit(); startEdit()
cd('/')
cmo.setAdministrationPortEnabled(true)
cmo.setAdministrationPort(9002)
save(); activate()
# then restart the server

Both match the pattern in weblogic/config-xml-admin-port — default values are simply omitted from config.xml, which is easy to misread as "unconfigured" rather than "off".

Operational traps hit while testing

Oracle JDK 21 download URLs under /java/21/latest/ now 404 — JDK 21 is no longer the current release, so the "latest" path serves whatever actually is latest. Fix: pin an explicit build under /java/21/archive/ (21.0.12 was the newest available there as of 2026-10-26; 21.0.13+ all 404 even in the archive, so Oracle's archive retention for a given major version is itself finite — expect to need to bump this again later). General rule: never leave an automated download pointed at a "latest"-style path for a version-pinned dependency; pin the resolved version and update it deliberately.

systemd Environment= with multiple -D flags in one value must be quoted. An unquoted line like Environment=JAVA_OPTIONS=-Dfoo=true -Dbar=300 is parsed by systemd as multiple whitespace-separated VAR=value assignments, not one value containing spaces — it silently truncates JAVA_OPTIONS to just -Dfoo=true and mis-handles the rest. Quote the whole assignment: Environment="JAVA_OPTIONS=-Dfoo=true -Dbar=300 ...".

created 2026-10-26  ·  tags weblogic, hsts, security, tested