{"record":{"id":"85db4829fddf9ecf","repo":"apache/pulsar","slug":"failed-to-find-ownership-for-serviceunit-s","errorCode":null,"errorMessage":"Failed to find ownership for ServiceUnit:%s","messagePattern":"Failed to find ownership for ServiceUnit:(.+?)","errorType":"http","errorClass":"RestException","httpStatus":412,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java","lineNumber":688,"sourceCode":"            boolean authoritative, boolean readOnly) {\n        return validateNamespaceBundleRangeAsync(fqnn, bundleRange)\n                .thenCompose(nsBundle -> validateBundleOwnershipAsync(nsBundle, authoritative, readOnly)\n                        .thenApply(__ -> nsBundle));\n    }\n\n    public CompletableFuture<Void> validateBundleOwnershipAsync(NamespaceBundle bundle, boolean authoritative,\n                                                                boolean readOnly) {\n        NamespaceService nsService = pulsar().getNamespaceService();\n        LookupOptions options = LookupOptions.builder()\n                .authoritative(authoritative)\n                .webServiceAdvertisedListenerName(getWebServiceListenerName())\n                .readOnly(readOnly)\n                .build();\n        return nsService.getLookupResultForWebRequestAsync(bundle, options)\n                .thenCompose(optLookupResult -> {\n                    if (optLookupResult.isEmpty()) {\n                        log.warn(\"Unable to get web service url\");\n                        throw new RestException(Status.PRECONDITION_FAILED,\n                                \"Failed to find ownership for ServiceUnit:\" + bundle.toString());\n                    }\n                    LookupResult lookupResult = optLookupResult.get();\n                    return nsService.isServiceUnitOwnedAsync(bundle)\n                            .thenAccept(owned -> {\n                                if (!owned) {\n                                    boolean newAuthoritative = this.isLeaderBroker();\n                                    UriBuilder uriBuilder = UriBuilder.fromUri(\n                                            lookupResult.toRedirectUri(uri.getRequestUri(), newAuthoritative));\n                                    if (!ExtensibleLoadManagerImpl.isLoadManagerExtensionEnabled(pulsar)) {\n                                        uriBuilder.replaceQueryParam(\"destinationBroker\");\n                                    }\n                                    URI redirect = uriBuilder.build();\n                                    log.debug().attr(\"bundle\", bundle).log(\"is not a service unit owned\");\n                                    // Redirect\n                                    log.debug().attr(\"redirect\", redirect).log(\"Redirecting the rest call\");\n                                    throw new WebApplicationException(Response.temporaryRedirect(redirect).build());\n                                }","sourceCodeStart":670,"sourceCodeEnd":706,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java#L670-L706","documentation":"validateBundleOwnershipAsync asks the load manager for a lookup result for the namespace bundle; if no broker currently owns (or is acquiring) that bundle, the Optional is empty and the resource throws 412 PRECONDITION_FAILED 'Failed to find ownership for ServiceUnit:...'. Normally an unowned bundle would be acquired, so this usually indicates the lookup machinery could not determine an owner.","triggerScenarios":"Admin operations on a namespace bundle (split/unload/clear-backlog under a bundle range) when getLookupResultForWebRequestAsync returns empty — e.g. namespace unloaded concurrently, no broker available to own the bundle, or lookup failing due to load-manager/service-url issues.","commonSituations":"Race with bundle unload/delete operations; namespace bundle data stale after broker restart; all brokers of the cluster down or registering slowly after failover; misconfigured advertised listeners so the lookup cannot produce a web service URL ('Unable to get web service url' in logs).","solutions":["Retry the request shortly after — ownership may settle once a broker acquires the bundle","Check broker availability and namespace status (pulsar-admin namespaces topics / broker stats)","Verify advertisedAddress/listeners and webServiceUrl config so lookups can resolve ('Unable to get web service url' preceding this error)","If a bundle is stuck, unload it: pulsar-admin namespaces unload <ns> --bundle <range>"],"exampleFix":"// before (immediately after unload, request fails 412)\n// after: wait and retry with backoff\nsleep 5s; pulsar-admin namespaces split-bundle my-tenant/ns/0x00000000_0xffffffff --unload","handlingStrategy":"retry","validationCode":"// Check the namespace has an owner before bundle operations\nList<String> bundles = admin.namespaces().getBundles(ns); // throws if namespace unassigned\n// also confirm brokers are registered\nif (admin.brokers().getActiveBrokers().length == 0) throw new IllegalStateException(\"no brokers available\");","typeGuard":null,"tryCatchPattern":"CompletableFuture\n    .supplyAsync(() -> doBundleOperation(bundle))\n    .exceptionallyCompose(ex -> {\n        if (isPreconditionFailed(ex) && ex.getMessage().contains(\"Failed to find ownership for ServiceUnit\")) {\n            return CompletableFuture.delayedExecutor(5, SECONDS)\n                .thenCompose(v -> doBundleOperation(bundle)); // bounded retries\n        }\n        return CompletableFuture.failedFuture(ex);\n    });","preventionTips":["Retry with backoff after unloads/bundle splits before admin calls","Monitor broker registration so lookups have candidates","Fix advertised listeners/webServiceUrl if you see 'Unable to get web service url'"],"tags":["http-412","namespace-bundle","ownership","load-manager"],"backgroundTag":"no-owner-for-service-unit","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}