eclipse-vertx/vert.x · error · IllegalStateException

Cannot have pipelining with no keep alive

Error message

Cannot have pipelining with no keep alive

What it means

TcpHttpClientTransport's constructor throws IllegalStateException when HTTP/1.x client options disable keep-alive but enable pipelining. Pipelining requires the connection to stay open to send multiple in-flight requests; with keep-alive disabled each connection closes after one response, making pipelining contradictory.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/tcp/TcpHttpClientTransport.java:112

  private final Duration writeIdleTimeout;
  private final WebSocketMetrics<?> webSocketMetrics;
  private final NetClientInternal client;

  public TcpHttpClientTransport(NetClientInternal netClient,
                                TracingPolicy tracingPolicy,
                                boolean useDecompression,
                                boolean logActivity,
                                ByteBufFormat logFormat,
                                boolean forceSni,
                                Http1ClientConfig http1Config,
                                Http2ClientConfig http2Config,
                                Duration idleTimeout,
                                Duration readIdleTimeout,
                                Duration writeIdleTimeout,
                                HttpClientMetrics<?, ?> webSocketMetrics) {

    if (http1Config != null && !http1Config.isKeepAlive() && http1Config.isPipelining()) {
      throw new IllegalStateException("Cannot have pipelining with no keep alive");
    }
    this.webSocketMetrics = webSocketMetrics;
    this.tracingPolicy = tracingPolicy;
    this.useDecompression = useDecompression;
    this.logActivity = logActivity;
    this.logFormat = logFormat;
    this.forceSni = forceSni;
    this.http1Config = http1Config;
    this.http2Config = http2Config;
    this.idleTimeout = idleTimeout != null ? idleTimeout : Duration.ofMillis(0);
    this.readIdleTimeout = readIdleTimeout != null ? readIdleTimeout : Duration.ofMillis(0);
    this.writeIdleTimeout = writeIdleTimeout != null ? writeIdleTimeout : Duration.ofMillis(0);
    this.client = netClient;
  }

  public NetClientInternal client() {
    return client;
  }

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Re-enable keep-alive: set keepAlive(true) on the HTTP/1.x config
  2. Disable pipelining: setPipelining(false) / pipelining limit 1 if keep-alive must stay off
  3. Review configuration files/env vars for a keep-alive=false override conflicting with pipelining defaults
  4. Validate the combination at config-load time and fail with a clearer message

Example fix

// before
options.setKeepAlive(false).setPipelining(true); // throws
// after
options.setKeepAlive(true).setPipelining(true);
// or
options.setKeepAlive(false).setPipelining(false);
Defensive patterns

Strategy: validation

Validate before calling

if (!http1Config.isKeepAlive() && http1Config.isPipelining()) { throw new IllegalArgumentException("Disable pipelining or enable keep-alive"); }
// then build transport

Try / catch

try { new TcpHttpClientTransport(...); } catch (IllegalStateException e) { log.error("Invalid HTTP/1 options: keep-alive off with pipelining on", e); }

Prevention

When it happens

Trigger: Constructing TcpHttpClientTransport (via HttpClientOptions / ClientOptions building) where http1Config is non-null, isKeepAlive() is false, and isPipelining() is true.

Common situations: Configuring HttpClientOptions with setKeepAlive(false) while leaving setPipelining(true) (or a non-1 pipelining limit); copying an existing config and only turning keep-alive off; framework defaults enabling pipelining while the user disables keep-alive.

Related errors


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/265ee94eccc73839. Report an issue: GitHub.