Application, Functions, and plugin upgrades to Pulsar 5.0.x
This guide covers application and extension changes when upgrading from Pulsar 4.x to 5.0.x. Use it alongside the Pulsar 5.0.x upgrade checklist and Configuration default changes.
Existing v4 applications do not need to change their client dependency or API merely to upgrade brokers. Review the checks relevant to your applications and complete server-side plugin, authentication, and TLS changes before rolling the affected components.
Java requirements
Pulsar 5.0 Java client libraries, including v4 and v5, client CLI tools, and the public Functions/IO interfaces remain compatible with Java 17. The server-side Functions implementation requires Java 21 or later; Functions compiled for Java 17 can run in a Java 21 or later Functions instance. Building broker plugins against broker-side libraries requires JDK 21 or later.
Choose Java client dependencies separately
For new Java applications or when updating client dependencies, use org.apache.pulsar:pulsar-client-v5-all. This recommended unshaded combined dependency includes the v4 client, v5 client, and admin implementation. pulsar-client-v5-shaded is a fallback only when unshaded dependency conflicts cannot be resolved. When adopting either artifact, replace the older separate client/admin dependencies and exclude transitive copies to avoid duplicate implementations; see Java client setup.
Dependency migration is separate from v5 API adoption. An application using either combined dependency can continue using the v4 API without enabling scalable-topic services. The v5 API requires those services even for regular topics; that requirement applies to API usage, not to the artifact's name. See the v4-to-v5 API migration guide.
Align application Netty dependencies
When adopting the unshaded pulsar-client-v5-all dependency, upgrade application dependencies from Netty 4.1.x to Netty 4.2.x. Pulsar uses 4.2.18.Final. Netty 4.2 is largely backward compatible with 4.1, but both lines cannot coexist on the same classpath. This dependency alignment is part of updating the application; it is not required merely to upgrade brokers while retaining an existing v4 client dependency.
Import io.netty:netty-bom alongside pulsar-bom, update framework-managed Netty versions, and verify that the resolved runtime graph and packaged application contain a consistent set of Netty modules without old or duplicate JARs. See the Maven and Gradle setup examples and the Netty migration guide.
Check schema dependencies
When upgrading Java client dependencies, review Avro class trust if your clients resolve application classes from externally supplied Avro schemas. Pulsar 5.0 also uses Protobuf 4 by default; check application dependency overrides against the resolved runtime.
Check authentication, TLS, and extensions
- TLS hostname verification is enabled by default for the Java client and outbound TLS connections from brokers, proxies, WebSocket services, and Functions workers. Check the hostnames used by client service URLs, advertised broker addresses, proxy-to-broker connections, and geo-replication. Reissue server certificates with matching subject alternative names before the rollout so both existing and upgraded components can connect. See Hostname verification.
- Custom TLS factories must be migrated. PIP-478 replaces the PIP-337
PulsarSslFactorySPI withPulsarTlsFactory. ReplacesslFactoryPlugin/sslFactoryPluginParamswithtlsFactoryClassName/tlsFactoryConfig, and replacebrokerClientSslFactoryPlugin/brokerClientSslFactoryPluginParamswithbrokerClientTlsFactoryClassName/brokerClientTlsFactoryConfig. Non-default values for the removed keys in broker/proxy configuration or clientloadConfmaps are rejected. When upgrading Java client/admin dependencies to 5.0, applications using the removed builder methods must be recompiled against the replacement methods. Also audit per-cluster TLS factory settings used by geo-replication: the oldClusterDatafields are retained but ignored by 5.0 brokers. Set their replacement fields withpulsar-admin clustersusing--tls-factory-class-nameand--tls-factory-config. - Proxy authentication: brokers now default to
authenticateOriginalAuthData=true. For deployments using TLS client-certificate or SASL authentication through a proxy, explicitly setauthenticateOriginalAuthData=falsein the broker configuration before rolling the brokers. The proxy's certificate does not authenticate the original client, and a SASL handshake cannot be replayed on the proxy-to-broker connection. Retain the appropriate trustedproxyRolesand authorization settings. Test both binary client connections and proxied HTTP admin requests with your real client identities. Proxied tenant administration requires both the proxy role and original principal to be authorized as a superuser or tenant administrator; granting that permission only to the proxy is insufficient. See Proxy configuration and Authorization. - Pulsar Broker plugins and extensions: use JDK 21 or later to build against broker-side libraries, which now target Java 21. Update plugin build environments and CI jobs, then rebuild and test against the target Pulsar release. Update extensions that use the affected Java EE APIs from
javax.*tojakarta.*at the Jakarta EE 10 level. The change does not rename everyjavaxpackage. Legacyjavax.servletAdditionalServletplugins are adapted for the new servlet environment; test their behavior along with other extensions. Adapt custom metadata-store implementations to the new overloads andSet<Option>hooks, includingMetadataCache<T>.put(String path, T value, Set<Option> opts); see Custom metadata-store implementations. Custom topic-policy listeners that rely on the initial namespace-wide notification may needtopicPolicyListenerReplayEnabled=true; it is disabled by default. See PIP-472 and Plugin development. - Custom managed-ledger integrations: remove calls to the unused
ManagedLedgerConfigaccessors formetadataEnsembleSize,metadataWriteQuorumSize, andmetadataAckQuorumSize; those Java fields and methods have been removed. The broker settingsmanagedLedgerDefaultEnsembleSize,managedLedgerDefaultWriteQuorum, andmanagedLedgerDefaultAckQuorumcontinue to supply default quorums, subject to persistence-policy overrides. - Broker interceptor ordering: hooks now run in the order listed in
brokerInterceptors. Check that order when one extension depends on work performed by an earlier hook. - Custom diagnostics libraries: replace calls to the removed
org.apache.pulsar:structured-event-logartifact andorg.apache.pulsar.structuredeventlogclasses. Code using theLatencyTracerAPI introduced in 4.2.4 must adapt: construct it with aNanoTimeSupplierwithout supplying aQueue<Timepoint>, and usegetTracePoints()andgetSnapshot().Timepoint,getLatency(), and the previous three-argumentSnapshotconstructor have been replaced. See Logging.
Before rolling brokers or upgrading clients, also exercise schema lookup, schema registration, and transactions with their production roles. When authorization is enabled, binary schema reads now require topic lookup authorization, schema registration requires produce authorization, and v4 transaction participant registration checks produce or subscription-specific consume authorization. Custom authorization providers must support these checks. See Schema and transaction authorization.
Check Functions behavior and extensions
- Python output message properties: the Python runtime now honors
forwardSourceMessageProperty. With the default worker settings, an omitted function setting enables copying input properties to the output. If downstream consumers rely on output properties without that forwarding, setforwardSourceMessageProperty: falsein the Function configuration and verify output properties before upgrading the runtime. This change concerns Python; Java already applied the setting, and this change does not add it to Go. See Python and Go runtime settings. - Custom worker extensions: rebuild and adapt plugins that use generated
org.apache.pulsar.functions.protoJava types to the LightProto API, including the top-levelFunctionDetailstype used byFunctionAuthProvider. See Custom worker extensions. - Java record implementations:
KVRecord<K, V>now extendsRecord<V>. When rebuilding a custom implementation, ensure thatgetValue()returnsV; an implementation that previously returnedObjectmay need adaptation.