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 notView on GitHub (pinned to 820761864e)
Solutions
- Configure the target broker's advertisedListeners/webServiceUrl so both http and https URLs are advertised (add TLS listener with advertisedListeners=...,tls... and webServiceUrlTls).
- Match the client scheme to what the target broker actually advertises (use http if no TLS URL is configured).
- Fix the advertised listener name in the request so it resolves to a listener that has the requested scheme's URL.
- 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
- Advertise both http and https web-service URLs (webServiceUrl + webServiceUrlTls) on every broker.
- Keep client scheme consistent with advertised listeners across the cluster.
- Include the TLS listener in advertisedListeners when terminating https anywhere in the path.
- Monitor for 412 responses on lookup endpoints as a config-drift signal.
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
- Issuer URL does not use https, but must:
- Failed to parse tlsFactoryConfig as a JSON object
- bindAddresses: ip:port `${ipPort}` is bound by two schemes:
- certFilePath must not be null
- keyFilePath must not be null
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/4ef5c4a28181c10b.
Report an issue: GitHub.