Skip to content

Fix #2249: stop the pulsar serviceUrl being URI-decoded twice - #2999

Merged
oscerd merged 1 commit into
apache:mainfrom
oscerd:ci-issue-2249
Sep 3, 2026
Merged

Fix #2249: stop the pulsar serviceUrl being URI-decoded twice#2999
oscerd merged 1 commit into
apache:mainfrom
oscerd:ci-issue-2249

Conversation

@oscerd

@oscerd oscerd commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes #2249.

Two years on, this still reproduces — I hit it on Camel 4.21 with the exact snippet from the issue:

Invalid service-url pulsar ssl://localhost:1234 provided
  Illegal character in scheme name at index 6: pulsar ssl://localhost:1234
Caused by: java.net.URISyntaxException

Cause

serviceUrl was interpolated straight into the endpoint URI:

- to:
    uri: pulsar:{{topicType}}/{{tenant}}/{{namespaceName}}/{{topic}}
    parameters:
      serviceUrl: "{{serviceUrl}}"

so the value is query-parameter decoded twice — once for the kamelet: URI the caller writes, and again when the template assembles pulsar:...?serviceUrl=. A + survives the first pass and becomes a space on the second, which is why the very common pulsar+ssl:// scheme reaches the Pulsar client as pulsar ssl://.

That is also exactly why the reporter's double-RAW() workaround works: one RAW per decode.

Fix

Wrap the placeholder in RAW() inside the template, protecting the value on the inner hop where the second decode happened:

-      serviceUrl: "{{serviceUrl}}"
+      serviceUrl: "RAW({{serviceUrl}})"

pulsar-source carried the identical interpolation, so it is fixed alongside — the report only mentions the sink, but the source would fail the same way against a TLS broker.

Verification

Ran both spellings against the real component. Neither produces the URISyntaxException any more, and the Pulsar client confirms the scheme survived:

what the user passes result
serviceUrl: pulsar+ssl://localhost:1234 No available hosts found for service url: pulsar+ssl://localhost:1234
serviceUrl: RAW(pulsar+ssl://localhost:1234) same

Reaching "no available hosts" is the success condition here — it means the URL parsed and the client tried to connect, with the + intact. There is no broker on localhost, which is all that fails.

Both spellings mattering is the point: the plain value now behaves as users expect, and the double-RAW workaround from the issue keeps working rather than breaking for anyone who already adopted it.

script/validator reports no errors and mvn clean install passes with tests from the repository root.

Note for reviewers

I scoped this to serviceUrl, the property in the report and the only one whose documented values routinely contain a +. The same double-decode applies in principle to any pulsar property carrying URI-significant characters — authenticationParams is the plausible next one — but I would rather not blanket-wrap properties on speculation, since RAW() also changes how a trailing ) is treated. Happy to extend it if you would prefer the whole parameter block hardened.


Claude Code on behalf of Andrea Cosentino

serviceUrl was interpolated raw into the pulsar endpoint URI, so its value
went through query parameter decoding twice: once for the kamelet: URI the
caller writes, and again when the template builds pulsar:...?serviceUrl=.
A "+" survives the first pass and becomes a space on the second, so the
common pulsar+ssl:// scheme arrives at the client as "pulsar ssl://":

  Invalid service-url pulsar ssl://localhost:1234 provided
  java.net.URISyntaxException: Illegal character in scheme name at index 6

Still reproduces on 4.21, two years after the report on 4.8.

Wrapping the placeholder in RAW() inside the template protects the value on
the inner hop, which is where the second decode happened. Verified both
ways against the real component:

  serviceUrl=pulsar+ssl://localhost:1234        -> resolves intact
  serviceUrl=RAW(pulsar+ssl://localhost:1234)   -> resolves intact

so the plain value now works as users expect, and the double-RAW workaround
from the issue keeps working rather than breaking. The Pulsar client
confirms the scheme survives:

  No available hosts found for service url: pulsar+ssl://localhost:1234

pulsar-source carried the identical interpolation and is fixed with it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@oscerd
oscerd merged commit 04658be into apache:main Sep 3, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pulsar-sink invalid character handling

1 participant