{"record":{"id":"cd7ecf42249f64f3","repo":"apache/pulsar","slug":"listener-name-name-must-contain-only-ascii-le","errorCode":null,"errorMessage":"listener name `${name}` must contain only ASCII letters, digits, underscore, or hyphen","messagePattern":"listener name `(.+?)` must contain only ASCII letters, digits, underscore, or hyphen","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-broker-common/src/main/java/org/apache/pulsar/broker/validator/MultipleListenerValidator.java","lineNumber":73,"sourceCode":"                ? host.substring(1, host.length() - 1) : host;\n        if (NetUtil.isValidIpV6Address(unbracketed)) {\n            return \"[\" + unbracketed + \"]:\" + uri.getPort();\n        }\n        return host + \":\" + uri.getPort();\n    }\n\n    /**\n     * Validate a listener name. Listener names must be non-blank and contain only ASCII letters,\n     * digits, underscore, and hyphen so they are safe to embed in URLs without encoding.\n     *\n     * @throws IllegalArgumentException if the name is null, blank, or contains disallowed characters.\n     */\n    public static void validateListenerName(String name) {\n        if (StringUtils.isBlank(name)) {\n            throw new IllegalArgumentException(\"listener name must not be blank\");\n        }\n        if (!LISTENER_NAME_PATTERN.matcher(name).matches()) {\n            throw new IllegalArgumentException(\"listener name `\" + name + \"` must contain only ASCII\"\n                    + \" letters, digits, underscore, or hyphen\");\n        }\n    }\n\n    /**\n     * Validate `advertisedListeners` and `internalListenerName`, returning the parsed listener map.\n     * <p>\n     * This method mutates the supplied {@link ServiceConfiguration}: when {@code internalListenerName}\n     * is blank, it is written back with the resolved fallback value (the first parsed listener if any,\n     * otherwise {@value ServiceConfiguration#DEFAULT_INTERNAL_LISTENER_NAME}) so that subsequent reads\n     * from the config see the effective value.\n     * <ol>\n     * <li>`advertisedListeners` is a comma-separated list of endpoints in the form\n     *     `listener:scheme://host:port`. Supported schemes are `pulsar`, `pulsar+ssl`, `http`, and `https`.\n     * <li>A listener name may be repeated to define multiple endpoints (e.g. binary and HTTPS) for the\n     *     same listener; duplicate definitions for the same scheme are rejected.\n     * <li>`internalListenerName` identifies the listener used for cluster-internal broker-to-broker\n     *     communication. It defaults to {@value ServiceConfiguration#DEFAULT_INTERNAL_LISTENER_NAME}.","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/validator/MultipleListenerValidator.java#L55-L91","documentation":"IllegalArgumentException thrown by MultipleListenerValidator.validateListenerName when the listener name contains characters outside ASCII letters, digits, underscore, and hyphen (LISTENER_NAME_PATTERN). Names must be safe to embed in URLs without percent-encoding, so characters like spaces, dots, colons, or non-ASCII letters are rejected.","triggerScenarios":"Configuring advertisedListeners or internalListenerName with names such as \"my listener\", \"pulsar.tls\", \"broker#1\", or Unicode names; validateBindAddresses also calls this on the name group of each bindAddresses entry.","commonSituations":"Using DNS-style dots in listener names (e.g. tls.internal); copying a hostname including dots as the listener name; localized/Unicode names from templating systems.","solutions":["Rename the listener using only [A-Za-z0-9_-], e.g. tls_internal or pulsar-tls","Update internalListenerName to match the renamed listener everywhere it is referenced","Keep listener names distinct from hostnames to avoid dot temptation"],"exampleFix":"// before\nadvertisedListeners=tls.internal:pulsar+ssl://host:6651\n// after\nadvertisedListeners=tls-internal:pulsar+ssl://host:6651","handlingStrategy":"validation","validationCode":"if (!name.matches(\"[A-Za-z0-9_-]+\")) {\n    throw new IllegalArgumentException(\"listener name '\" + name + \"' must contain only ASCII letters, digits, underscore, or hyphen\");\n}","typeGuard":"static boolean isValidListenerName(String name) {\n    return name != null && name.matches(\"[A-Za-z0-9_-]+\");\n}","tryCatchPattern":null,"preventionTips":["Restrict names to [A-Za-z0-9_-]; avoid dots, spaces, colons","Keep listener names distinct from hostnames","Enforce the pattern in Helm/Ansible templates","Mirror the same pattern in any UI that generates configs"],"tags":["configuration","listener-name","validation","multi-listener"],"backgroundTag":"invalid-listener-name","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}