apache/hadoop · error · IllegalArgumentException

Expecting arguments size of at most two, getting {}

Error message

Expecting arguments size of at most two, getting {}

What it means

ShellCommandFencer.parseArgs() throws IllegalArgumentException('Expecting arguments size of at most two, getting [...]') when the shell fencing argument split on the ',' delimiter (ARG_DELIMITER) yields more than two segments. The two-segment form is 'commandForActiveTransition,commandForStandbyTransition' selected by the target's transition HA state; three or more parts are rejected.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ha/ShellCommandFencer.java:146

      outPumper.join();
    } catch (InterruptedException ie) {
      LOG.warn("Interrupted while waiting for fencing command: " + cmd);
      return false;
    }
    
    return rc == 0;
  }

  private String parseArgs(HAServiceProtocol.HAServiceState state,
      String cmd) {
    String[] args = cmd.split(ARG_DELIMITER);
    if (args.length == 1) {
      // only one command is given, assuming both src and dst
      // will execute the same command/script.
      return args[0];
    }
    if (args.length > 2) {
      throw new IllegalArgumentException("Expecting arguments size of at most "
          + "two, getting " + Arrays.asList(args));
    }
    if (HAServiceProtocol.HAServiceState.ACTIVE.equals(state)) {
      return args[0];
    } else if (HAServiceProtocol.HAServiceState.STANDBY.equals(state)) {
      return args[1];
    } else {
      throw new IllegalArgumentException(
          "Unexpected HA service state:" + state);
    }
  }

  /**
   * Abbreviate a string by putting '...' in the middle of it,
   * in an attempt to keep logs from getting too messy.
   * @param cmd the string to abbreviate
   * @param len maximum length to abbreviate to
   * @return abbreviated string

View on GitHub (pinned to 2add963021)

Solutions

  1. Remove commas from the command: move the logic into a script file and call it, e.g. 'shell(/opt/fence.sh)'.
  2. Keep at most one comma, separating the active-state variant from the standby-state variant: 'shell(/opt/fence_active.sh,/opt/fence_standby.sh)'.
  3. Check the exception's argument list ([a, b, c]) to see exactly how the string was split.

Example fix

<!-- before: three comma-split segments -->
<value>shell(/opt/fence.sh primary,standby,observer)</value>

<!-- after: at most two segments (active variant, standby variant) -->
<value>shell(/opt/fence.sh primary,/opt/fence.sh standby)</value>
Defensive patterns

Strategy: validation

Validate before calling

// Mirror ShellCommandFencer's split before shipping the config
String shellArg = argInsideParens; // from 'shell(...)'
if (shellArg.split(",").length > 2) {
  throw new IllegalStateException(
      "shell fencer arg splits into >2 comma segments: " + shellArg);
}

Try / catch

try {
  fencer.fence(target); // internally parses args
} catch (IllegalArgumentException iae) {
  if (iae.getMessage().startsWith("Expecting arguments size")) {
    // rewrite the command to remove commas (move logic into a script)
  }
}

Prevention

When it happens

Trigger: The configured shell command itself contains commas, e.g. 'shell(/bin/fence.sh a,b,c)' or an inline pipeline with commas (awk scripts, comma-separated host lists), so cmd.split(",") produces 3+ parts and parseArgs throws before the command ever runs.

Common situations: Inlining awk/sed/grep pipelines that contain commas instead of putting them in a script file; specifying active/standby command variants plus one extra comma-separated token; note this is an unchecked IllegalArgumentException (not BadFencingConfigurationException) and surfaces at tryFence time.

Related errors


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