apache/pulsar · error · IllegalArgumentException
httpReverseProxy.%s.proxyTo must be specified exactly once
Error message
httpReverseProxy.%s.proxyTo must be specified exactly once
What it means
ProxyConfiguration.loadConfig validates that every httpReverseProxy.<name> block defines both a path and a proxyTo key exactly once. When a block omits httpReverseProxy.<name>.proxyTo (or path), the configuration cannot determine the upstream target the reverse proxy should forward to, so it refuses to start. This fail-fast validation prevents silently proxying to a null/undefined target.
Source
Thrown at pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConfiguration.java:1120
public void setProperties(Properties properties) {
this.properties = properties;
Map<String, Map<String, String>> redirects = new HashMap<>();
Pattern redirectPattern = Pattern.compile("^httpReverseProxy\\.([^\\.]*)\\.(.+)$");
Map<String, List<Matcher>> groups = properties.stringPropertyNames().stream()
.map((s) -> redirectPattern.matcher(s))
.filter(Matcher::matches)
.collect(Collectors.groupingBy((m) -> m.group(1))); // group by name
groups.entrySet().forEach((e) -> {
Map<String, String> keyToFullKey = e.getValue().stream().collect(
Collectors.toMap(m -> m.group(2), m -> m.group(0)));
if (!keyToFullKey.containsKey("path")) {
throw new IllegalArgumentException(
String.format("httpReverseProxy.%s.path must be specified exactly once", e.getKey()));
}
if (!keyToFullKey.containsKey("proxyTo")) {
throw new IllegalArgumentException(
String.format("httpReverseProxy.%s.proxyTo must be specified exactly once", e.getKey()));
}
httpReverseProxyConfigs.add(new HttpReverseProxyConfig(e.getKey(),
properties.getProperty(keyToFullKey.get("path")),
properties.getProperty(keyToFullKey.get("proxyTo"))));
});
}
public static class HttpReverseProxyConfig {
private final String name;
private final String path;
private final String proxyTo;
HttpReverseProxyConfig(String name, String path, String proxyTo) {
this.name = name;
this.path = path;
this.proxyTo = proxyTo;
}View on GitHub (pinned to 820761864e)
Solutions
- Add the missing key to the block, e.g. httpReverseProxy.<name>.proxyTo=http://localhost:8080
- Verify the key spelling is exactly 'proxyTo' (camelCase, no underscores) and both path and proxyTo exist for the same <name>
- Remove any orphaned/partial httpReverseProxy blocks for services no longer in use
- Validate config in CI by constructing ProxyConfiguration and calling loadConfig on the file before deploy
Example fix
// before httpReverseProxy.functions.path=/admin/functions // after httpReverseProxy.functions.path=/admin/functions httpReverseProxy.functions.proxyTo=http://localhost:6750
Defensive patterns
Strategy: validation
Validate before calling
Properties props = loadProperties();
Set<String> names = props.stringPropertyNames().stream()
.filter(k -> k.startsWith("httpReverseProxy."))
.map(k -> k.split("\\.")[1])
.collect(Collectors.toSet());
for (String name : names) {
if (props.getProperty("httpReverseProxy." + name + ".path") == null
|| props.getProperty("httpReverseProxy." + name + ".proxyTo") == null) {
throw new IllegalArgumentException("httpReverseProxy." + name + " must define both path and proxyTo");
}
} Type guard
boolean hasCompleteReverseProxyBlock(Properties props, String name) {
return props.getProperty("httpReverseProxy." + name + ".path") != null
&& props.getProperty("httpReverseProxy." + name + ".proxyTo") != null;
} Try / catch
try {
config.loadConfig(props);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("httpReverseProxy")) {
LOG.error("Invalid reverse proxy block, check path/proxyTo keys: {}", e.getMessage());
}
throw e;
} Prevention
- Always define path and proxyTo as a pair for each httpReverseProxy.<name> block
- Use exact camelCase key names (proxyTo, not proxyto)
- Lint proxy config files in CI by loading them with ProxyConfiguration before deploy
- Delete stale reverse-proxy blocks when removing upstream services
When it happens
Trigger: Calling ProxyConfiguration.loadConfig with properties that contain an httpReverseProxy.<name> block where httpReverseProxy.<name>.path is set but httpReverseProxy.<name>.proxyTo is missing (or vice versa); also triggered when the regex key extraction yields a group whose key-to-fullKey map lacks the 'proxyTo' entry, e.g. duplicate/malformed key names like httpReverseProxy.<name>.proxyTo defined with a typo such as proxyto.
Common situations: Hand-editing proxy config files and typo-ing 'proxyTo' as 'proxyto' or 'proxy_to'; copy-pasting a reverse-proxy block from docs and deleting the proxyTo line; leaving a stale block behind after removing an upstream service; migration from older configs that only had path.
Related errors
- Invalid IP address filter '${ipAddressString}'
- httpReverseProxy.%s.path must be specified exactly once
- Timeout during delete operation
- Timeout during close operation
- Timeout during open-cursor operation
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/f991fd94e9385a20.
Report an issue: GitHub.