apache/hadoop · error · IOException

Can't replace _HOST pattern since client address is null

Error message

Can't replace _HOST pattern since client address is null

What it means

SecurityUtil.getServerPrincipal(principalConfig, addr) replaces the _HOST placeholder (the second component of a principal like hdfs/_HOST@REALM) using a hostname derived from the supplied InetAddress. When the principal uses _HOST but addr is null, there is no way to derive the host, so an IOException is thrown rather than returning a broken principal.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java:230

   * 
   * @param principalConfig
   *          Kerberos principal name pattern to convert
   * @param addr
   *          InetAddress of the host used for substitution
   * @return converted Kerberos principal name
   * @throws IOException if the client address cannot be determined
   */
  @InterfaceAudience.Public
  @InterfaceStability.Evolving
  public static String getServerPrincipal(String principalConfig,
      InetAddress addr) throws IOException {
    String[] components = getComponents(principalConfig);
    if (components == null || components.length != 3
        || !components[1].equals(HOSTNAME_PATTERN)) {
      return principalConfig;
    } else {
      if (addr == null) {
        throw new IOException("Can't replace " + HOSTNAME_PATTERN
            + " pattern since client address is null");
      }
      return replacePattern(components, domainNameResolver.getHostnameByIP(addr));
    }
  }
  
  private static String[] getComponents(String principalConfig) {
    if (principalConfig == null)
      return null;
    return principalConfig.split("[/@]");
  }
  
  private static String replacePattern(String[] components, String hostname)
      throws IOException {
    String fqdn = hostname;
    if (fqdn == null || fqdn.isEmpty() || fqdn.equals("0.0.0.0")) {
      fqdn = getLocalHostName(null);
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Use the single-argument overload SecurityUtil.getServerPrincipal(principalConfig) when local-host substitution is intended
  2. Use SecurityUtil.getServerPrincipal(principalConfig, hostname) with an explicit hostname string when no InetAddress is available
  3. Otherwise pass the server's non-null address (commonly socket.getInetAddress()) before calling
  4. Restrict _HOST usage to daemon-side principal configs; client-side configs should name the host explicitly

Example fix

// before
String principal = SecurityUtil.getServerPrincipal(principalConfig, (InetAddress) null);

// after
String principal = SecurityUtil.getServerPrincipal(principalConfig, serverHostname); // String-hostname overload
Defensive patterns

Strategy: validation

Validate before calling

String[] c = principalConfig.split("[/@]");
boolean usesHostPattern = c.length == 3 && "_HOST".equals(c[1]);
if (usesHostPattern && addr == null) {
  // pick an overload that does not need an address
  return SecurityUtil.getServerPrincipal(principalConfig);
}

Type guard

static boolean hostSubstitutable(String principalConfig, InetAddress addr) {
  String[] c = principalConfig == null ? new String[0] : principalConfig.split("[/@]");
  boolean usesHost = c.length == 3 && "_HOST".equals(c[1]);
  return !usesHost || addr != null;
}

Prevention

When it happens

Trigger: Calling getServerPrincipal(principalConfig, (InetAddress) null) or a wrapper that passes a null address while the configured principal contains _HOST; typically client-side code that has not yet opened a socket to the server, or unit tests passing null.

Common situations: Client code copied from server login paths that legitimately has no server address yet; refactors that dropped the address argument; tests exercising principal substitution with null inputs.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/d92bb26215f988cf. Report an issue: GitHub.