Branch/Environment/Version
- Branch/Version: All active releases (v5.8.x LTS through master, verified on v5.8.5, v5.8.12-rc1, v5.9.2, v5.10.2, v5.11.1, release-5.12, master)
- Environment: All (On-prem/Hybrid/MDCB)
Describe the bug
Tyk Gateway forces TLS 1.2 as the maximum version for upstream (outbound) TLS connections, preventing TLS 1.3 negotiation. This is caused by two separate code issues:
Bug 1 — Inverted condition in gateway/api_loader.go
// gateway/api_loader.go:168 (master)
if spec.Proxy.Transport.SSLMaxVersion > 0 { // BUG: should be == 0
spec.Proxy.Transport.SSLMaxVersion = tls.VersionTLS12
}
The intent is to set a default when the value is unconfigured (== 0), but the condition > 0 overwrites any explicitly set value back to TLS 1.2. Setting ssl_max_version: 772 (TLS 1.3) in an API definition gets reset to 771 (TLS
1.2) because 772 > 0 is true.
Bug 2 — Global default hardcodes TLS 1.2 in gateway/server.go
// gateway/server.go:1571 (master)
if gwConfig.ProxySSLMaxVersion == 0 {
gwConfig.ProxySSLMaxVersion = tls.VersionTLS12
}
In Go's crypto/tls, MaxVersion = 0 means "negotiate the highest supported version" (TLS 1.3 in Go 1.18+). Tyk treats 0 as "not configured" and forces it to TLS 1.2, contradicting Go's standard behavior. The same pattern exists for
downstream at line 1579.
Reproduction steps
Steps to reproduce the behavior:
- Deploy Tyk Gateway with default config (no
proxy_ssl_max_version set)
- Create an API with an upstream that supports TLS 1.3
- Observe that the connection is negotiated at TLS 1.2, not TLS 1.3
To verify via API-level config:
- Set
proxy.transport.ssl_max_version: 772 in an API definition
- Observe the value is overwritten to
771 (TLS 1.2) by api_loader.go:168
Actual behavior
- All upstream TLS connections are capped at TLS 1.2
- API-level
ssl_max_version setting is silently ignored (overwritten)
Expected behavior
A clear and concise description of what you expected to happen.
- With no config: TLS version should be negotiated up to TLS 1.3 (Go default)
- With
ssl_max_version: 772: TLS 1.3 should be used as the maximum version
Screenshots/Video
If applicable, add screenshots or video to help explain your problem.
Logs (debug mode or log file):
Not applicable — no error is logged. The TLS version downgrade happens silently during config initialization.
Configuration (tyk config file):
Default configuration (no TLS version settings):
{
"proxy_ssl_max_version": 0,
"proxy_ssl_min_version": 0
}
Additional context
Add any other context about the problem here.
Affected code locations across branches:
| Branch |
api_loader.go (Bug 1) |
server.go (Bug 2) |
| master |
line 168 |
line 1571, 1579 |
| v5.8.12-rc1 (LTS) |
line 164 |
line 1503, 1511 |
| v5.9.2 |
line 180 |
line 1400, 1408 |
| v5.10.2 |
line 167 |
line 1468, 1476 |
| v5.11.1 |
line 167 |
line 1477, 1485 |
| release-5.12 |
line 167 |
line 1571, 1579 |
Workaround:
- Gateway level: Set
TYK_GW_PROXYSSLMAXVERSION=772 (or "proxy_ssl_max_version": 772 in tyk.conf)
- API level: Set both
ssl_min_version: 772 and ssl_max_version: 772 (min > max correction at api_loader.go:172 restores the value, but this results in TLS 1.3 only — no TLS 1.2 fallback)
Proposed fix:
api_loader.go:168 — Change > 0 to == 0
server.go:1571, 1579 — Change default from tls.VersionTLS12 to tls.VersionTLS13 (update outdated 2021 default to reflect current TLS landscape)
I would like to submit a PR for this fix. Backport to release-5.8 (LTS) would be appreciated as well.
Branch/Environment/Version
Describe the bug
Tyk Gateway forces TLS 1.2 as the maximum version for upstream (outbound) TLS connections, preventing TLS 1.3 negotiation. This is caused by two separate code issues:
Bug 1 — Inverted condition in
gateway/api_loader.goThe intent is to set a default when the value is unconfigured (
== 0), but the condition> 0overwrites any explicitly set value back to TLS 1.2. Settingssl_max_version: 772(TLS 1.3) in an API definition gets reset to771(TLS1.2) because
772 > 0is true.Bug 2 — Global default hardcodes TLS 1.2 in
gateway/server.goIn Go's
crypto/tls,MaxVersion = 0means "negotiate the highest supported version" (TLS 1.3 in Go 1.18+). Tyk treats0as "not configured" and forces it to TLS 1.2, contradicting Go's standard behavior. The same pattern exists fordownstream at line 1579.
Reproduction steps
Steps to reproduce the behavior:
proxy_ssl_max_versionset)To verify via API-level config:
proxy.transport.ssl_max_version: 772in an API definition771(TLS 1.2) byapi_loader.go:168Actual behavior
ssl_max_versionsetting is silently ignored (overwritten)Expected behavior
A clear and concise description of what you expected to happen.
ssl_max_version: 772: TLS 1.3 should be used as the maximum versionScreenshots/Video
If applicable, add screenshots or video to help explain your problem.
Logs (debug mode or log file):
Not applicable — no error is logged. The TLS version downgrade happens silently during config initialization.
Configuration (tyk config file):
Default configuration (no TLS version settings):
{ "proxy_ssl_max_version": 0, "proxy_ssl_min_version": 0 }Additional context
Add any other context about the problem here.
Affected code locations across branches:
api_loader.go(Bug 1)server.go(Bug 2)Workaround:
TYK_GW_PROXYSSLMAXVERSION=772(or"proxy_ssl_max_version": 772in tyk.conf)ssl_min_version: 772andssl_max_version: 772(min > max correction atapi_loader.go:172restores the value, but this results in TLS 1.3 only — no TLS 1.2 fallback)Proposed fix:
api_loader.go:168— Change> 0to== 0server.go:1571, 1579— Change default fromtls.VersionTLS12totls.VersionTLS13(update outdated 2021 default to reflect current TLS landscape)I would like to submit a PR for this fix. Backport to
release-5.8(LTS) would be appreciated as well.