{"record":{"id":"b275721c71d773a1","repo":"eclipse-vertx/vert.x","slug":"missing-authority-host-header","errorCode":null,"errorMessage":"Missing :authority / host header","messagePattern":"Missing :authority / host header","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/http/impl/http2/DefaultHttp2ClientStream.java","lineNumber":156,"sourceCode":"    private final boolean end;\n    private final Promise<Void> promise;\n\n    public HeadersWrite(HttpRequestHead request, ByteBuf buf, boolean end, Promise<Void> promise) {\n      this.request = request;\n      this.buf = buf;\n      this.end = end;\n      this.promise = promise;\n    }\n\n    @Override\n    public void write() {\n      HttpRequestHeaders headers = new HttpRequestHeaders(new DefaultHttp2Headers());\n      headers.method(request.method);\n      headers.trace(request.traceOperation);\n      boolean e;\n      if (request.method == HttpMethod.CONNECT) {\n        if (request.authority == null) {\n          throw new IllegalArgumentException(\"Missing :authority / host header\");\n        }\n        headers.authority(request.authority);\n        // don't end stream for CONNECT\n        e = false;\n      } else {\n        headers.path(request.uri);\n        headers.scheme(connection.isSsl() ? \"https\" : \"http\");\n        if (request.authority != null) {\n          headers.authority(request.authority);\n        }\n        e = end;\n      }\n      if (request.headers != null && !request.headers.isEmpty()) {\n        for (Map.Entry<String, String> header : request.headers) {\n          CharSequence headerName = HttpUtils.toLowerCase(header.getKey());\n          if (!AsciiString.contentEquals(TRANSFER_ENCODING, headerName)) {\n            headers.add(headerName, header.getValue());\n          }","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/http/impl/http2/DefaultHttp2ClientStream.java#L138-L174","documentation":"When opening an HTTP/2 CONNECT stream, DefaultHttp2ClientStream requires the request to have an :authority (host) pseudo-header. For CONNECT requests there is no absolute path to derive the authority from, so it must be set explicitly; otherwise the HTTP/2 frame would be malformed per RFC 7540. Vert.x throws IllegalArgumentException before the stream is created.","triggerScenarios":"Calling HttpClient.request(HttpMethod.CONNECT, ...) or building an HTTP/2 CONNECT request without setting the host/authority on the RequestOptions.","commonSituations":"Writing a tunnel/proxy client (CONNECT to an upstream host) where the developer passes only a port or omits setHost(); porting HTTP/1.1 CONNECT code that relied on the Host header being synthesized.","solutions":["Set the host on RequestOptions: new RequestOptions().setMethod(HttpMethod.CONNECT).setHost(\"example.com\").setPort(443).","Ensure the authority (host[:port]) string is non-null before sending the request.","For generic requests, prefer setServer or a full absolute URI so authority is populated."],"exampleFix":"// before\nRequestOptions opts = new RequestOptions().setMethod(HttpMethod.CONNECT).setURI(\"/tunnel\");\n// after\nRequestOptions opts = new RequestOptions()\n  .setMethod(HttpMethod.CONNECT)\n  .setHost(\"upstream.example.com\")\n  .setPort(443);","handlingStrategy":"validation","validationCode":"if (options.getHost() == null || options.getHost().isEmpty()) throw new IllegalArgumentException(\"CONNECT requires host\");","typeGuard":null,"tryCatchPattern":"try { client.request(opts); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\":authority\")) { opts.setHost(defaultAuthority); client.request(opts); } }","preventionTips":["Always setHost/setPort for CONNECT requests","Build a RequestOptions factory that enforces host presence","Unit-test CONNECT option building","Prefer absolute URIs so authority is derivable"],"tags":["http2","connect","missing-header","client"],"backgroundTag":"missing-required-argument","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}