apache/druid · error · IllegalArgumentException

plaintextPort and tlsPort cannot be null or same if both htt

Error message

plaintextPort and tlsPort cannot be null or same if both http and https connectors are enabled

What it means

When both plaintext and TLS listeners are enabled, DruidNode requires both ports to be set and distinct. If either port is null or they are equal, init() throws IAE since the two Jetty connectors would collide or one would be missing.

Source

Thrown at server/src/main/java/org/apache/druid/server/DruidNode.java:197

    Integer portFromHostConfig;
    if (host != null) {
      hostAndPort = HostAndPort.fromString(host);
      host = hostAndPort.getHost();
      portFromHostConfig = hostAndPort.hasPort() ? hostAndPort.getPort() : null;
      if (plainTextPort != null && portFromHostConfig != null && !plainTextPort.equals(portFromHostConfig)) {
        throw new IAE("Conflicting host:port [%s] and port [%d] settings", host, plainTextPort);
      }
      if (portFromHostConfig != null) {
        plainTextPort = portFromHostConfig;
      }
    } else {
      host = getDefaultHost();
    }

    if (enablePlaintextPort && enableTlsPort && ((plainTextPort == null || tlsPort == null)
                                                 || plainTextPort.equals(tlsPort))) {
      // If both plainTExt and tls are enabled then do not allow plaintextPort to be null or
      throw new IAE("plaintextPort and tlsPort cannot be null or same if both http and https connectors are enabled");
    }
    if (enableTlsPort && (tlsPort == null || tlsPort < 0)) {
      throw new IAE("A valid tlsPort needs to specified when druid.enableTlsPort is set");
    }

    if (enablePlaintextPort) {
      // to preserve backwards compatible behaviour
      if (nullHost && plainTextPort == null) {
        plainTextPort = -1;
      } else {
        if (plainTextPort == null) {
          plainTextPort = SocketUtil.findOpenPort(8080);
        }
      }
      this.plaintextPort = plainTextPort;
    } else {
      this.plaintextPort = -1;
    }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Set distinct values for druid.port and druid.tlsPort (e.g. 8081 and 8281)
  2. Ensure the druid.tlsPort key exists in every enabled node's runtime.properties
  3. Keep TLS and plaintext port assignments separate in your config templates

Example fix

// before
  druid.enablePlaintextPort=true
  druid.enableTlsPort=true
  druid.port=8081
  druid.tlsPort=8081
// after
  druid.port=8081
  druid.tlsPort=8281
Defensive patterns

Strategy: validation

Validate before calling

if (enablePlaintextPort && enableTlsPort
    && (plainPort == null || tlsPort == null || plainPort.equals(tlsPort))) {
  throw new IllegalArgumentException("Set distinct non-null druid.port and druid.tlsPort");
}

Try / catch

try {
  node = new DruidNode(service, host, true, plainPort, tlsPort, false, false);
} catch (IllegalArgumentException e) {
  log.fatal("Bad TLS/port config: %s", e.getMessage());
  throw e;
}

Prevention

When it happens

Trigger: druid.enablePlaintextPort=true and druid.enableTlsPort=true with druid.tlsPort unset, druid.port unset, or both set to the same number.

Common situations: TLS enablement added without adding a tlsPort value; copy-pasting druid.port into druid.tlsPort; property files where the port key was renamed and the old one lost.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/59b6403e736f9b75. Report an issue: GitHub.