apple/pkl · error · IllegalArgumentException

invalidHttpHeaderValue

invalidHttpHeaderValue

Error message

HTTP header value `{0}` has invalid syntax.

What it means

The HTTP header value failed Pkl's value syntax check (headerValueLike regex), which permits only valid visible characters per RFC 7230 field-value rules (no control characters like newlines, NUL, or non-ASCII bytes outside the accepted set). Thrown from IoUtils.validateHeaderValue.

Solutions

  1. Trim the value and strip control characters/newlines before configuring it.
  2. Re-encode the value (e.g. Base64-encode binary/unicode data) so it consists of allowed characters.
  3. Escape or normalize the source (env var, secret manager) that introduces the illegal characters.

Example fix

// before
["X-Trace"] = "abc\n123"
// after
["X-Trace"] = "abc123"
Defensive patterns

Strategy: validation

Validate before calling

if (value == null || value.chars().anyMatch(c -> c < 32 && c != '\t') || value.chars().anyMatch(c -> c > 126 && c < 160)) throw new IllegalArgumentException("bad header value");

Prevention

When it happens

Trigger: Passing a header value containing newlines, tabs in invalid positions, control characters, or non-Latin-1 characters to validateHeaderValue / external HTTP header config, e.g. a multi-line value or a value pasted with a trailing \n.

Common situations: Values interpolated from secrets or environment variables that carry trailing newlines; pasted API keys with hidden control characters; building headers from raw user input.

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 apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/976811fce4b771a6. Report an issue: GitHub.

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/util/IoUtils.java:949

  public static void validateHeaderName(String headerName) {
    if (isReservedHeaderName(headerName)) {
      throw new IllegalArgumentException(
          ErrorMessages.create("invalidHttpHeaderReserved", headerName));
    }

    if (hasReservedHeaderPrefix(headerName)) {
      throw new IllegalArgumentException(
          ErrorMessages.create("invalidHttpHeaderReservedPrefix", headerName));
    }

    if (!headerNameLike.matcher(headerName).matches()) {
      throw new IllegalArgumentException(ErrorMessages.create("invalidHttpHeaderName", headerName));
    }
  }

  public static void validateHeaderValue(String headerValue) {
    if (!headerValueLike.matcher(headerValue).matches()) {
      throw new IllegalArgumentException(
          ErrorMessages.create("invalidHttpHeaderValue", headerValue));
    }
    if (headerValue.length() > 4096) {
      throw new IllegalArgumentException(
          ErrorMessages.create("invalidHttpHeaderValueTooLong", headerValue));
    }
  }

  private static @Nullable String getFilenameExtension(String fileName) {
    var dotIndex = fileName.lastIndexOf('.');
    // 0 if hidden file (e.g. `.gitignore`); not an extension
    if (dotIndex == -1 || dotIndex == 0) {
      return null;
    }
    return fileName.substring(dotIndex + 1);
  }

  public static @Nullable Path findExecutableOnPath(String executable) {

View on GitHub (pinned to f3efcbfc9b)