quarkusio/quarkus · error · RuntimeException

Failed to create URI

Error message

Failed to create URI

What it means

UriBuilderImpl wraps any exception from URI.create(buf) when turning the fully-substituted template string into a java.net.URI. It means the interpolated URI string is syntactically invalid per RFC 2396 (illegal characters, bad scheme/authority form), not that a template value was missing. The underlying parse exception is chained as the cause.

Solutions

  1. Inspect the chained cause (e.getCause()) to see the exact illegal character or position reported by URI.create
  2. Pre-encode parameter values with URLEncoder.encode(v, UTF_8) or pass them through UriBuilder.resolveTemplate/queryParam which encode automatically
  3. Remove or fix the offending characters in the template or map values (e.g. replace spaces with %20)
  4. Validate the final string with URI.create() in dev to catch this early

Example fix

// before
URI uri = UriBuilder.fromUri("https://api.example.com/{q}").build("raw value with space");
// after
URI uri = UriBuilder.fromUri("https://api.example.com").queryParam("q", "{q}").build("raw value with space");
Defensive patterns

Strategy: validation

Validate before calling

String s = builder.clone().build(params).toString(); // or pre-check in dev
// validate values before build:
for (Map.Entry<String, ?> e : paramMap.entrySet()) {
    Object v = e.getValue();
    if (v != null && (v.toString().contains(" ") || v.toString().contains("{"))) {
        throw new IllegalArgumentException("Value for " + e.getKey() + " contains characters needing URI encoding");
    }
}

Type guard

static boolean isUriSafe(String s) {
    return s != null && java.net.URI.create(s).toString().equals(s) == false || s.chars().allMatch(c -> c > 32 && c < 127 && c != '{' && c != '}' && c != '|');
}

Try / catch

try {
    URI uri = builder.build(params);
} catch (RuntimeException e) {
    if (e.getCause() != null) throw new IllegalStateException("Invalid URI string: " + e.getCause().getMessage(), e);
    throw e;
}

Prevention

When it happens

Trigger: Calling UriBuilder.build(Map)/buildFromMap/buildFromEncodedMap where a supplied parameter value introduces characters illegal in a URI (unencoded spaces, '{', '|', non-ASCII) or produces a malformed authority/scheme, so URI.create() on the built string throws.

Common situations: User path/query values taken from user input or config containing spaces or unicode; forgetting that build() (not buildFromEncoded()) encodes values; building URIs from concatenated string templates with raw data; property values with trailing junk copied from docs.

Related errors


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

Appendix: source

Thrown at independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/jaxrs/UriBuilderImpl.java:528

        if (values == null)
            throw new IllegalArgumentException("Values parameter is null");
        return buildUriFromMap(values, true, false);
    }

    public URI buildFromMap(Map<String, ?> values, boolean encodeSlashInPath)
            throws IllegalArgumentException, UriBuilderException {
        if (values == null)
            throw new IllegalArgumentException("Values parameter is null");
        return buildUriFromMap(values, false, encodeSlashInPath);
    }

    protected URI buildUriFromMap(Map<String, ? extends Object> paramMap, boolean fromEncodedMap, boolean encodeSlash)
            throws IllegalArgumentException, UriBuilderException {
        String buf = buildString(paramMap, fromEncodedMap, false, encodeSlash);
        try {
            return URI.create(buf);
        } catch (Exception e) {
            throw new RuntimeException("Failed to create URI", e);
        }
    }

    private String buildString(Map<String, ? extends Object> paramMap, boolean fromEncodedMap, boolean isTemplate,
            boolean encodeSlash) {
        return buildCharSequence(paramMap, fromEncodedMap, isTemplate, encodeSlash).toString();
    }

    private CharSequence buildCharSequence(Map<String, ? extends Object> paramMap, boolean fromEncodedMap, boolean isTemplate,
            boolean encodeSlash) {
        StringBuilder builder = new StringBuilder();

        if (scheme != null)
            replaceParameter(paramMap, fromEncodedMap, isTemplate, scheme, builder, encodeSlash).append(":");
        if (ssp != null) {
            builder.append(ssp);
        } else if (userInfo != null || host != null || port != -1) {
            builder.append("//");

View on GitHub (pinned to e1c734241f)