eclipse-vertx/vert.x · error · IllegalArgumentException

a header name cannot contain non-ASCII character: <value>

Error message

a header name cannot contain non-ASCII character: <value>

What it means

HTTP header names must be ASCII (RFC 7230 token characters). When a header name given as a Netty AsciiString contains a byte with the high bit set (byte < 0, i.e. a non-ASCII byte ≥ 0x80), Vert.x throws this IllegalArgumentException during validateHeaderName.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/HttpUtils.java:840

    if (value instanceof AsciiString) {
      // no need to check for ASCII-ness anymore
      validateAsciiHeaderName((AsciiString) value);
    } else if(value instanceof String) {
      validateStringHeaderName((String) value);
    } else {
      validateSequenceHeaderName(value);
    }
  }

  private static void validateAsciiHeaderName(AsciiString value) {
    final int len = value.length();
    final int off = value.arrayOffset();
    final byte[] asciiChars = value.array();
    for (int i = 0; i < len; i++) {
      // Check to see if the character is not an ASCII character, or invalid
      byte c = asciiChars[off + i];
      if (c < 0) {
        throw new IllegalArgumentException("a header name cannot contain non-ASCII character: " + value);
      }
      if (!VALID_H_NAME_ASCII_CHARS[c & 0x7F]) {
        throw new IllegalArgumentException("a header name cannot contain some prohibited characters, such as : " + value);
      }
    }
  }

  private static void validateStringHeaderName(String value) {
    for (int i = 0; i < value.length(); i++) {
      final char c = value.charAt(i);
      // Check to see if the character is not an ASCII character, or invalid
      if (c > 0x7f) {
        throw new IllegalArgumentException("a header name cannot contain non-ASCII character: " + value);
      }
      if (!VALID_H_NAME_ASCII_CHARS[c & 0x7F]) {
        throw new IllegalArgumentException("a header name cannot contain some prohibited characters, such as : " + value);
      }
    }

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Use ASCII-only header names (letters, digits, and token characters like '-').
  2. Move non-ASCII information (e.g. a language tag) into the header value or a standard parameter instead of the name.
  3. If the name comes from external input, validate it matches [A-Za-z0-9-]+ before passing it to Vert.x.

Example fix

// before
headers.set(AsciiString.cached("X-Utilisateur-Français"), "v"); // non-ASCII -> throws
// after
headers.set(AsciiString.cached("X-User-Locale"), "fr-FR");
Defensive patterns

Strategy: validation

Validate before calling

public static boolean isAsciiHeaderName(String name) {
  for (int i = 0; i < name.length(); i++) {
    if (name.charAt(i) > 0x7F) return false;
  }
  return true;
}

Try / catch

try {
  request.putHeader(name, value);
} catch (IllegalArgumentException e) {
  throw new IllegalArgumentException("Header name must be ASCII: " + name);
}

Prevention

When it happens

Trigger: Calling putHeader/removeHeader with an AsciiString name that contains bytes ≥ 0x80, e.g. a name built from UTF-8 encoded text like "X-Naïve" or localized header names.

Common situations: Constructing header names from user input or i18n labels; converting a UTF-8 String to AsciiString without checking its contents; older data pipelines that assumed Latin-1 header names.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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