Skip to content

[fix][broker] Spurious ERROR log for 307 redirect in getReplicatedSubscriptionStatus - #26706

Merged
lhotari merged 3 commits into
apache:masterfrom
Goodkat:fix/spurious-error-log-for-307
Sep 28, 2026
Merged

lhotari merged 3 commits into
apache:masterfrom
Goodkat:fix/spurious-error-log-for-307

Conversation

@Goodkat

@Goodkat Goodkat commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Fixes #26699

Motivation

PersistentTopicsBase#internalGetReplicatedSubscriptionStatusForNonPartitionedTopic logs every
failure of its future at ERROR level with a full stack trace. That includes the
WebApplicationException: HTTP 307 Temporary Redirect thrown by validateTopicOwnershipAsync
when this broker does not own the topic.

A 307 is not a failure. It is how a broker tells the caller which broker owns the partition; the
caller follows the redirect and the operation succeeds. Logging it at ERROR is misleading and
noisy:

"log.level":"ERROR",
"message":"Failed to get replicated subscription status on <topic> <subscription>",
"error.type":"jakarta.ws.rs.WebApplicationException",
"error.message":"HTTP 307 Temporary Redirect"

The redirect is reached often in practice. For a partitioned topic,
internalGetReplicatedSubscriptionStatus checks ownership per partition and forwards the
partitions this broker does not own to their owning brokers through the internal admin client.
The receiving broker takes the partitioned-name path into
internalGetReplicatedSubscriptionStatusForNonPartitionedTopic, and if ownership moved in the
meantime — a bundle unload or a rebalance between the lookup and the call — it answers 307 and
logs the stack trace. With geo-replication, many partitions, and monitoring that polls
replicated subscription status, this fills broker logs with ERROR entries for healthy traffic.

Every comparable handler in the admin API already filters these out with
isNot307And404Exception, including the outer resultFuture.exceptionally handler in this very
method. The guard is missing only in this inner handler.

Modifications

Wrap the log.error(...) call in internalGetReplicatedSubscriptionStatusForNonPartitionedTopic
in an isNot307And404Exception(cause) check, matching the pattern used throughout
PersistentTopicsBase.

This is a logging-only change. The exception is still propagated to the caller unchanged through
resumeAsyncResponseExceptionally, so the 307 response, the redirect location, and client
behaviour are all exactly as before. Genuine failures are still logged at ERROR; only 307 and 404
are suppressed.

Verifying this change

  • Make sure that the change passes the CI checks.

This change added tests and can be verified as follows:

  • Added PersistentTopicsTest#testGetReplicatedSubscriptionStatusDoesNotLogRedirectAsError,
    which stubs NamespaceService#isServiceUnitOwnedAsync to report the partition as not owned —
    the same state a concurrent bundle unload produces — then calls
    getReplicatedSubscriptionStatus with the partition name so the request routes directly into
    the handler under test. It asserts both that the response is still 307 Temporary Redirect
    and that no ERROR event was logged for it.
  • The test captures log events from the PulsarWebResource logger rather than
    PersistentTopicsBase: the log field used by this handler is inherited from
    PulsarWebResource and derived via LOG.with().build(), and slog preserves the parent
    logger's name when deriving. Registering on PersistentTopicsBase would capture nothing and
    the test would pass vacuously.
  • Verified the test is load-bearing by reverting the production change and re-running it: it
    fails with AssertionError: A 307 redirect must not be logged at ERROR level.

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

If the box was checked, please highlight the changes

  • Dependencies (add or upgrade a dependency)
  • The public API
  • The schema
  • The default values of configurations
  • The threading model
  • The binary protocol
  • The REST endpoints
  • The admin CLI options
  • The metrics
  • Anything that affects deployment

@Goodkat

Goodkat commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

Could anyone review this?
Thank you.

@lhotari lhotari left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the contribution @Goodkat

@lhotari
lhotari merged commit 776786b into apache:master Sep 28, 2026
43 checks passed
@Goodkat
Goodkat deleted the fix/spurious-error-log-for-307 branch September 29, 2026 06:43
ascentstream-bot pushed a commit to ascentstream/pulsar that referenced this pull request Oct 1, 2026
…scriptionStatus (apache#26706)

Co-authored-by: Vyacheslav SHABLISTYY <[email protected]>
Co-authored-by: Lari Hotari <[email protected]>
(cherry picked from commit 776786b)
ascentstream-bot pushed a commit to ascentstream/pulsar that referenced this pull request Oct 2, 2026
…scriptionStatus (apache#26706)

Co-authored-by: Vyacheslav SHABLISTYY <[email protected]>
Co-authored-by: Lari Hotari <[email protected]>
(cherry picked from commit 776786b)
Radiancebobo pushed a commit to Radiancebobo/pulsar that referenced this pull request Oct 8, 2026
…scriptionStatus (apache#26706)

Co-authored-by: Vyacheslav SHABLISTYY <[email protected]>
Co-authored-by: Lari Hotari <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Spurious ERROR log for 307 redirect in getReplicatedSubscriptionStatus for partitioned topics

2 participants