quarkusio/quarkus · error · IllegalArgumentException

Path must always start with a path separator, but was '' cre

Error message

Path must always start with a path separator, but was '' created from original path pattern ''

What it means

Quarkus HTTP security path matching requires every registered permission path to be absolute, i.e. it must begin with '/'. The ImmutablePathMatcher builder validates this when a path (possibly produced by normalizing an original pattern) is added; if it does not start with a separator it throws IllegalArgumentException. When the failing path differs from the original configured pattern, both are included in the message to help locate the misconfiguration.

Source

Thrown at extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/ImmutablePathMatcher.java:249

         */
        public ImmutablePathMatcherBuilder<T> addPath(String path, T handler) {
            if (empty) {
                empty = false;
            }
            path = path.trim();
            if (rootPath != null && !path.startsWith("/")) {
                path = rootPath + path;
            }
            return addPath(path, path, handler);
        }

        private ImmutablePathMatcherBuilder<T> addPath(String originalPath, String path, T handler) {
            if (!path.startsWith("/")) {
                String errMsg = "Path must always start with a path separator, but was '" + path + "'";
                if (!originalPath.equals(path)) {
                    errMsg += " created from original path pattern '" + originalPath + "'";
                }
                throw new IllegalArgumentException(errMsg);
            }
            final int wildcardIdx = path.indexOf('*');
            if (wildcardIdx == -1) {
                addExactPath(path, handler);
            } else {
                addWildcardPath(path, handler, wildcardIdx, originalPath);
            }
            return this;
        }

        private void addWildcardPath(String path, T handler, int wildcardIdx, String originalPath) {
            final int lastIdx = path.length() - 1;
            final String pathWithWildcard;
            final String pathAfter1stWildcard;

            if (lastIdx == wildcardIdx) {
                // ends with a wildcard => it's a prefix path
                pathWithWildcard = path;

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add a leading '/' to every path in the permission's paths list (e.g. paths=/foo/*).
  2. If the path is built programmatically, ensure the result is absolute before calling addPath (prepend '/' when missing).
  3. Check the original pattern in the message: fix the source configuration so normalization does not yield an empty/relative path.

Example fix

// before (application.properties)
quarkus.http.auth.permission.public.paths=api/*
// after
quarkus.http.auth.permission.public.paths=/api/*
Defensive patterns

Strategy: validation

Validate before calling

boolean isAbsoluteHttpPath(String p) { return p != null && p.startsWith("/"); }
// check every quarkus.http.auth.permission.<name>.paths entry before deployment

Prevention

When it happens

Trigger: Registering a path into ImmutablePathMatcherBuilder via addPath where the (possibly rewritten) path string is empty or does not start with '/', e.g. quarkus.http.auth.permission.<name>.paths=foo/* or a blank/relative entry in application.properties.

Common situations: Typos in quarkus.http.auth.permission paths config (missing leading slash), paths generated programmatically from relative values, or empty string after removing a prefix from a configured pattern.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/dee0a6c87ceaf94d. Report an issue: GitHub.