Skip to content

[fix][broker] Reject topic names with leading or trailing whitespace on creation - #26281

Open
crossoverJie wants to merge 7 commits into
apache:masterfrom
crossoverJie:fix-topic-name-trailing-whitespace
Open

[fix][broker] Reject topic names with leading or trailing whitespace on creation#26281
crossoverJie wants to merge 7 commits into
apache:masterfrom
crossoverJie:fix-topic-name-trailing-whitespace

Conversation

@crossoverJie

Copy link
Copy Markdown
Member

Motivation

Creating a topic whose local name has leading or trailing whitespace
(e.g. persistent://public/default/test-topic-x ) succeeds via the admin
API, but producing to / consuming from it fails with
TopicDoesNotExistException when allowAutoTopicCreation=false.

Root cause: Pulsar clients (Java ConsumerBuilder / ProducerBuilder /
ReaderBuilder) trim topic names, so the client resolves to the trimmed
name while the created znode keeps the whitespace (Codec encodes the space
as +). The orphaned topic can never be reached — and can't even be deleted,
because the delete path also trims the name and returns 404.

Rejecting on creation is preferred over server-side trimming: trimming would
silently reroute non-Java clients (Go/C++/Python, which do not trim) to a
different name after an upgrade, and would make already-broken whitespace
topics un-deletable.

Modifications

  • TopicName: added isValidForCreation(TopicName) and
    validateTopicNameForCreation(TopicName) — reject leading/trailing
    whitespace in the local name; internal whitespace (e.g. my topic) stays
    allowed.

  • Broker admin creation paths now reject with HTTP 412
    (PreconditionFailedException) instead of persisting an unreachable topic:

    • Centralized create-time validation in
      AdminResource.validateCreateTopic(TopicName) (moved from
      PersistentTopicsBase) so persistent, non-persistent and scalable
      topics share one source of truth.
    • BrokerService.isAllowAutoTopicCreationAsync returns false for such
      names, so auto-creation is also refused (covers clients that do not trim).
  • Client admin fail-fast: TopicsImpl (partitioned + non-partitioned),
    NonPersistentTopicsImpl, and ScalableTopicsImpl now reject whitespace
    names locally and fail the future with PreconditionFailedException (412),
    consistent with the server response — so callers catching
    PreconditionFailedException work for both the client fast-fail and the
    server path.

Verifying this change

This change added tests and can be verified as follows:

  • pulsar-common: TopicNameTest.testValidateTopicNameForCreation
  • pulsar-broker (broker-api):
    ConsumerCreationTest.testCreatePartitionedTopicWithTrailingWhitespaceIsRejected
    (regression for the original bug; creation is rejected and the trimmed
    name still works)
  • pulsar-broker (broker-admin):
    PersistentTopicsTest.testCreateTopicWithSurroundingWhitespaceIsRejected
    (asserts 412 for persistent/non-persistent partitioned + non-partitioned)
  • pulsar-broker:
    BrokerServiceAutoTopicCreationTest.testAutoTopicCreationRejectsSurroundingWhitespace
    (auto-creation refused, no topic left behind)
  • pulsar-broker (broker-admin):
    ScalableTopicsListByPropertyTest.testCreateScalableTopicWithSurroundingWhitespaceIsRejected
    (asserts 412 for scalable topic creation)
  • Run: ./gradlew quickCheck plus the scoped tests above.

Does this pull request potentially affect one of the following parts:

  • The REST endpoints — topic create endpoints now return 412
    (PreconditionFailedException) for names with leading/trailing
    whitespace instead of persisting an unreachable topic.
  • The public API — the admin client now rejects (412) topic names with
    leading/trailing whitespace that were previously accepted; this is a
    behavioral correction of a bug. Callers that never sent whitespace
    names are unaffected.
  • Dependencies
  • The schema
  • The default values of configurations
  • The threading model
  • The binary protocol
  • The admin CLI options
  • The metrics
  • Anything that affects deployment

…espace

Signed-off-by: crossoverJie <crossoverJie@gmail.com>
Signed-off-by: crossoverJie <crossoverJie@gmail.com>
Signed-off-by: crossoverJie <crossoverJie@gmail.com>
Signed-off-by: crossoverJie <crossoverJie@gmail.com>
Signed-off-by: crossoverJie <crossoverJie@gmail.com>
…alableTopicsListByPropertyTest

Signed-off-by: crossoverJie <crossoverJie@gmail.com>
…Test

Signed-off-by: crossoverJie <crossoverJie@gmail.com>
@crossoverJie
crossoverJie requested review from lhotari and nodece August 6, 2026 13:29
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.

2 participants