apache/pulsar · error · WebApplicationException

No ${scheme} URL configured for broker ${brokerId}

Error message

No ${scheme} URL configured for broker ${brokerId}

What it means

LookupResult.toRedirectUriInternal builds an HTTP redirect to another broker using the target broker's HTTP/HTTPS web-service URL. If the target broker's lookup data has no URL for the requested scheme (request was https but only an http URL is advertised, or vice versa), it throws WebApplicationException with HTTP 412 PRECONDITION_FAILED and message 'No <scheme> URL configured for broker <id>'.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/lookup/LookupResult.java:289

    }

    private URI toRedirectUriInternal(URI requestUri, boolean authoritativeRedirect,
                                      boolean injectListenerNameQueryParam) {
        boolean requireHttps = "https".equalsIgnoreCase(requestUri.getScheme());
        String webServiceUrl = requireHttps ? lookupData.getHttpUrlTls() : lookupData.getHttpUrl();
        if (webServiceUrl == null) {
            // Preserve the legacy 412 error semantics when the redirect target broker has no URL
            // configured for the requested scheme.
            String scheme = requireHttps ? "https" : "http";
            StringBuilder entity = new StringBuilder()
                    .append("No ").append(scheme).append(" URL configured for broker ")
                    .append(lookupData.getBrokerId());
            if (StringUtils.isNotBlank(webServiceListenerName)) {
                entity.append(" on web service listener `").append(webServiceListenerName).append("`");
            } else if (StringUtils.isNotBlank(brokerServiceListenerName)) {
                entity.append(" on listener `").append(brokerServiceListenerName).append("`");
            }
            throw new WebApplicationException(Response.status(Response.Status.PRECONDITION_FAILED)
                    .entity(entity.toString())
                    .build());
        }
        URI webServiceUri = URI.create(webServiceUrl);
        UriBuilder uriBuilder =
                UriBuilder.fromUri(requestUri) // use the path and query parameters from the request URI
                        .scheme(webServiceUri.getScheme()) // use the schema from the lookup result
                        .host(webServiceUri.getHost())  // use the host from the lookup result
                        .port(webServiceUri.getPort()); // use the port from the lookup result
        if (isRedirect()) {
            // pass the authoritative parameter only when the type is redirect
            uriBuilder.replaceQueryParam("authoritative", authoritativeRedirect);
        } else {
            // remove the parameter when the type is not redirect
            uriBuilder.replaceQueryParam("authoritative");
        }
        // Only set the listenerName query parameter on topic-lookup redirects. The original lookup
        // request can carry it either as a query parameter or as a header; the latter does not

View on GitHub (pinned to 820761864e)

Solutions

  1. Configure the target broker's advertisedListeners/webServiceUrl so both http and https URLs are advertised (add TLS listener with advertisedListeners=...,tls... and webServiceUrlTls).
  2. Match the client scheme to what the target broker actually advertises (use http if no TLS URL is configured).
  3. Fix the advertised listener name in the request so it resolves to a listener that has the requested scheme's URL.
  4. Handle the 412 PRECONDITION_FAILED response in the client by falling back to direct lookup on the advertised URL that does exist.

Example fix

# before (broker.conf)
advertisedListeners=http:localhost:8080
# after
advertisedListeners=http:localhost:8080,https:localhost:8443
webServiceUrl=http://localhost:8080
webServiceUrlTls=https://localhost:8443
Defensive patterns

Strategy: try-catch

Validate before calling

boolean https = "https".equalsIgnoreCase(requestUri.getScheme());
String url = https ? lookupData.getHttpUrlTls() : lookupData.getHttpUrl();
if (url == null) { /* target cannot serve this scheme; pick another broker or fail fast */ }

Type guard

boolean canRedirect(LookupData d, boolean https) {
    return d != null && (https ? d.getHttpUrlTls() != null : d.getHttpUrl() != null);
}

Try / catch

try {
    URI redirect = lookupResult.toRedirectUri(requestUri);
    return Response.temporaryRedirect(redirect).build();
} catch (WebApplicationException e) {
    if (e.getResponse().getStatus() == 412) {
        return Response.status(Response.Status.SERVICE_UNAVAILABLE)
            .entity(e.getResponse().getEntity()).build();
    }
    throw e;
}

Prevention

When it happens

Trigger: A REST lookup/admin redirect occurs where the incoming request scheme is https but the redirect target's advertisedListeners/webServiceUrl lacks a TLS URL (or the request is http but only TLS URL exists), including when a specific advertised listener was selected.

Common situations: Broker advertises only non-TLS listeners while clients use https (or the reverse); advertisedListeners misconfigured without the right scheme; TLS configured on the proxy but not on the redirect-target broker; listenerName resolving to a listener without the required URL.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/4ef5c4a28181c10b. Report an issue: GitHub.