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.
-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 version | Listener | enableHSTS | Header sent? | Value |
|---|---|---|---|---|
| 12.2.1.4 | SSL (7002) | false | No | — |
| 12.2.1.4 | SSL (7002) | true | Yes | max-age=31536000; includeSubDomains; preload |
| 12.2.1.4 | admin port | true | Yes | max-age=31536000; includeSubDomains; preload |
| 12.2.1.4 | HTTP (7001) | true | No | — |
| 14.1.2.0 | SSL (7002) | false | No | — |
| 14.1.2.0 | SSL (7002) | true | Yes | max-age=31536000; includeSubDomains; preload |
| 14.1.2.0 | SSL (7002), custom | true | Yes | max-age=300 (includeSubDomains/preload correctly dropped when the matching flags are set false) |
| 14.1.2.0 | admin port | true | Yes | max-age=31536000; includeSubDomains; preload |
| 14.1.2.0 | HTTP (7001) | true | No | — |
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.
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".
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 ...".