eclipse-vertx/vert.x · error
426 Upgrade Required (RFC2817)
Error message
426 Upgrade Required (RFC2817)
What it means
SC_UPGRADE_REQUIRED is an HttpResponseExpectation constant for HTTP 426 (RFC2817). The server requires the client to switch to a different protocol (e.g. HTTP to TLS) via the Upgrade header before retrying the request. Vert.x exposes it for status expectations on HttpClient requests.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/http/HttpResponseExpectation.java:265
/** * 423 Locked (WebDAV, RFC4918) */ HttpResponseExpectation SC_LOCKED = status(423); /** * 424 Failed Dependency (WebDAV, RFC4918) */ HttpResponseExpectation SC_FAILED_DEPENDENCY = status(424); /** * 425 Unordered Collection (WebDAV, RFC3648) */ HttpResponseExpectation SC_UNORDERED_COLLECTION = status(425); /** * 426 Upgrade Required (RFC2817) */ HttpResponseExpectation SC_UPGRADE_REQUIRED = status(426); /** * 428 Precondition Required (RFC6585) */ HttpResponseExpectation SC_PRECONDITION_REQUIRED = status(428); /** * 429 Too Many Requests (RFC6585) */ HttpResponseExpectation SC_TOO_MANY_REQUESTS = status(429); /** * 431 Request Header Fields Too Large (RFC6585) */ HttpResponseExpectation SC_REQUEST_HEADER_FIELDS_TOO_LARGE = status(431); /** * Any 5XX server error
View on GitHub (pinned to fb308bd8c3)
Solutions
- Switch the client request to TLS/HTTPS (RequestOptions setSsl(true), port 443).
- Retry with the required Upgrade header and protocols listed in the 426 response.
- Update hardcoded http:// URLs to https:// in configuration after server policy changes.
- If testing upgrade behavior, keep the expectation; otherwise expect 101 Switching Protocols after a valid upgrade.
Example fix
// before
client.request(new RequestOptions().setHost("api.example.com").setPort(80))
// after
client.request(new RequestOptions().setHost("api.example.com").setPort(443).setSsl(true)) Defensive patterns
Strategy: fallback
Validate before calling
if ("http".equals(requestOptions.getUri().substring(0, 4)) && serverRequiresTls) {
requestOptions.setSsl(true).setPort(443);
} Type guard
boolean is426(HttpClientResponse resp) { return resp.statusCode() == 426; } Try / catch
plainRequest().onFailure(err -> {
if (isCauseStatus(err, 426)) retryWithUpgradeOrTls();
}); Prevention
- Prefer https endpoints by default
- Read the Upgrade header on 426 and honor the listed protocols
- Audit configs after TLS-enforcement changes
- Test protocol-upgrade behavior in CI
When it happens
Trigger: Sending a plain-HTTP request to a server that mandates TLS (responds 426 with an Upgrade header), or any endpoint requiring protocol upgrade before the request is accepted. Appears when .expecting(SC_UPGRADE_REQUIRED) is used to test upgrade behavior or when a non-ssl client hits an SSL-required server.
Common situations: Server hardened to require HTTPS after deprecating plain HTTP; misconfigured client still using http:// for an https-only endpoint; WebSocket endpoints requiring a proper Upgrade handshake.
Related errors
- Not listening
- 421 Misdirected Request
- 422 Unprocessable Entity (WebDAV, RFC4918)
- 423 Locked (WebDAV, RFC4918)
- 424 Failed Dependency (WebDAV, RFC4918)
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/1f295cc6ba987681.
Report an issue: GitHub.