grpc/grpc-java · error · IllegalArgumentException

Invalid header key:

Error message

Invalid header key: 

What it means

HeaderValueValidationUtils.validateHeaderKey checks that a header key is non-null, non-empty, and within MAX_HEADER_LENGTH. Keys violating these rules cause an IllegalArgumentException including the offending key. It guards HTTP/2 header-name rules before ext_proc mutations are applied.

Source

Thrown at xds/src/main/java/io/grpc/xds/internal/grpcservice/HeaderValueValidationUtils.java:36

import com.google.protobuf.ByteString;
import java.util.Locale;

/**
 * Utility class for validating HTTP headers.
 */
public final class HeaderValueValidationUtils {
  public static final int MAX_HEADER_LENGTH = 16384;

  private HeaderValueValidationUtils() {}

  /**
   * Validates that the header key is non-empty and within allowed length.
   * Throws {@link IllegalArgumentException} if invalid.
   */
  public static void validateHeaderKey(String key) {
    if (key == null || key.isEmpty() || key.length() > MAX_HEADER_LENGTH) {
      throw new IllegalArgumentException("Invalid header key: " + key);
    }
  }

  /**
   * Validates that the header value is within allowed length and contains valid ASCII characters.
   * Throws {@link IllegalArgumentException} if invalid.
   */
  public static void validateHeaderValue(String key, String value) {
    validateHeaderKey(key);
    if (value == null || value.length() > MAX_HEADER_LENGTH) {
      throw new IllegalArgumentException("Header value length exceeds maximum allowed length");
    }
    if (!key.endsWith("-bin") && !isValidAsciiHeaderValue(value)) {
      throw new IllegalArgumentException(
          "Invalid ASCII characters in header value for key: " + key);
    }
  }

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Fix the ext_proc server so every HeaderValue carries a valid, non-empty key within the length limit
  2. Validate/sanitize keys on the mutation producer before returning them
  3. Reject or log-and-skip invalid header mutations in your processor logic
  4. Keep header names short and lowercase per HTTP/2 conventions

Example fix

// before
HeaderValue.newBuilder().setValue("abc").build() // missing key
// after
HeaderValue.newBuilder().setKey("x-user-id").setValue("abc").build()
Defensive patterns

Strategy: validation

Validate before calling

if (key == null || key.isEmpty() || key.length() > HeaderValueValidationUtils.MAX_HEADER_LENGTH) { rejectMutation(); }

Type guard

null

Try / catch

try { HeaderValueValidationUtils.validateHeaderKey(key); }
catch (IllegalArgumentException e) { log.warn("Dropping invalid header mutation", e); }

Prevention

When it happens

Trigger: validateHeaderKey (directly or via validateHeaderValue) receives a null key, an empty "" key, or a key longer than MAX_HEADER_LENGTH — typically from an ext_proc header-mutation response.

Common situations: ext_proc server returning HeaderValue protos with unset key; middleware constructing headers programmatically and forgetting the name; config-driven header injection with a blank key template.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/97530993f3cd3186. Report an issue: GitHub.