apache/hadoop · error · IllegalArgumentException

Illegal field separator: ${separator}

Error message

Illegal field separator: ${separator}

What it means

CallerContext.Builder joins audit fields with a configurable separator, and rejects three separators that would corrupt the audit string: tab (\t), newline (\n), and equals (=). The separator comes from the Builder(String, String) overload or, in production, from the hadoop.caller.context.separator config (default '#'). Constructing the Builder with any illegal value throws this IllegalArgumentException.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/CallerContext.java:164

    }

    public Builder(String context, String separator) {
      if (isValid(context)) {
        sb.append(context);
      }
      fieldSeparator = separator;
      checkFieldSeparator(fieldSeparator);
    }

    /**
     * Check whether the separator is legal.
     * The illegal separators include '\t', '\n', '='.
     * Throw IllegalArgumentException if the separator is Illegal.
     * @param separator the separator of fields.
     */
    private void checkFieldSeparator(String separator) {
      if (ILLEGAL_SEPARATORS.contains(separator)) {
        throw new IllegalArgumentException("Illegal field separator: "
            + separator);
      }
    }

    /**
     * Whether the field is valid.
     * @param field one of the fields in context.
     * @return true if the field is not null or empty.
     */
    private boolean isValid(String field) {
      return field != null && field.length() > 0;
    }

    public Builder setSignature(byte[] signature) {
      if (signature != null && signature.length > 0) {
        this.signature = Arrays.copyOf(signature, signature.length);
      }
      return this;

View on GitHub (pinned to 2add963021)

Solutions

  1. Pick a legal separator such as '#' (the default) or '-'.
  2. Audit the effective value: hadoop conf or conf.get("hadoop.caller.context.separator").
  3. In XML, avoid numeric character refs tricks that inject tab/newline into the property.
  4. If you need key=value styling inside a field, use ':' (KEY_VALUE_SEPARATOR) within fields and keep the field separator '#'.

Example fix

# before
<property><name>hadoop.caller.context.separator</name><value>=</value></property>
new CallerContext.Builder("app", conf); // throws: Illegal field separator: =

# after
<property><name>hadoop.caller.context.separator</name><value>#</value></property>
new CallerContext.Builder("app", conf).add("op", "scan");
Defensive patterns

Strategy: validation

Validate before calling

String sep = conf.get("hadoop.caller.context.separator", "#");
if ("\t".equals(sep) || "\n".equals(sep) || "=".equals(sep)) {
  throw new IllegalArgumentException("hadoop.caller.context.separator must not be tab, newline or '=': " + sep);
}

Type guard

static boolean isLegalCallerContextSeparator(String s) {
  return s != null && !("\t".equals(s) || "\n".equals(s) || "=".equals(s));
}

Try / catch

try {
  CallerContext context = new CallerContext.Builder("app", conf).build();
} catch (IllegalArgumentException e) {
  // separator config is illegal; fall back to the default '#'
  CallerContext context = new CallerContext.Builder("app").build();
}

Prevention

When it happens

Trigger: Setting hadoop.caller.context.separator to '=', a literal tab, or '\n' (XML often encodes these as &amp;#9;/&amp;#10; and they arrive as real control characters); building CallerContext programmatically via new CallerContext.Builder(context, "=").

Common situations: Teams structuring caller contexts as key=value pairs and choosing '=' as the field separator, which collides with the reserved KEY_VALUE_SEPARATOR ':'-style semantics and audit parsing; YAML/XML configs where an escaped tab or newline slips into the value; migrating apps that used ad-hoc separators.

Related errors


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