apple/pkl · error · IllegalArgumentException

Rewrite rule must start with 'http://' or 'https://', but…

Error message

Rewrite rule must start with 'http://' or 'https://', but was '%s'

What it means

validateRewriteRule checks URI-rewrite rules used to redirect remote module fetches. A rule must be an http:// or https:// URI; this IllegalArgumentException is thrown for rules with any other scheme (file:, package:, relative, etc.).

Solutions

  1. Use an http:// or https:// base URI for the rewrite target
  2. Fix the scheme in the rewrite configuration entry
  3. Remove the rule if a local override is not supported

Example fix

// before
rewrite { ["example.com/mypackage/"] = "file:///local/mypackage/" }
// after
rewrite { ["example.com/mypackage/"] = "https://localhost:8080/mypackage/" }
Defensive patterns

Strategy: validation

Validate before calling

URI r = URI.create(ruleStr);
if (!r.getScheme().equals("http") && !r.getScheme().equals("https")) throw new IllegalArgumentException("rewrite rule must be http(s)");

Type guard

function isHttpUri(u) { return u != null && (u.getScheme().equals("http") || u.getScheme().equals("https")); }

Try / catch

try { IoUtils.validateRewriteRule(rewrite) } catch (IllegalArgumentException e) { /* report bad scheme in rewrite config */ }

Prevention

When it happens

Trigger: Passing a rewrite rule URI with a non-http(s) scheme to validateRewriteRule, e.g. via --rewrite-settings or a rewrite block in PklProject configuration pointing at file: or a relative URI.

Common situations: Misconfiguring module rewrites by pointing them at a local directory instead of an HTTP mirror, or forgetting the scheme in the config value.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/d455e466e1006717. Report an issue: GitHub.

Appendix: source

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

  private static int getExclamationMarkIndex(String jarUri) {
    var index = jarUri.indexOf('!');
    if (index == -1) {
      throw new IllegalArgumentException("Invalid `jar:` URI (missing `!`): " + jarUri);
    }
    return index;
  }

  public static void validateFileUri(URI uri) throws URISyntaxException {
    if (!uri.getSchemeSpecificPart().startsWith("/")) {
      throw new URISyntaxException(uri.toString(), ErrorMessages.create("invalidOpaqueFileUri"));
    }
  }

  public static void validateRewriteRule(URI rewrite) {
    if (!Objects.equals(rewrite.getScheme(), "http")
        && !Objects.equals(rewrite.getScheme(), "https")) {
      throw new IllegalArgumentException(
          "Rewrite rule must start with 'http://' or 'https://', but was '%s'".formatted(rewrite));
    }

    if (!rewrite.toString().endsWith("/")) {
      throw new IllegalArgumentException(
          "Rewrite rule must end with '/', but was '%s'".formatted(rewrite));
    }
  }

  private static boolean isReservedHeaderName(String headerName) {
    var normalizedHeader = headerName.toLowerCase(Locale.ROOT);
    for (var reservedHeader : reservedHeaderNames) {
      if (normalizedHeader.equals(reservedHeader)) {
        return true;
      }
    }
    return false;
  }

View on GitHub (pinned to f3efcbfc9b)