{"record":{"id":"5712703518a2a431","repo":"apache/pulsar","slug":"error-while-scanning-ledgers-for-namespacename","errorCode":null,"errorMessage":"Error while scanning ledgers for ${namespaceName}","messagePattern":"Error while scanning ledgers for (.+?)","errorType":"http","errorClass":"RestException","httpStatus":500,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/Namespaces.java","lineNumber":3631,"sourceCode":"                            out.append(\"\\\"errors\\\": \" + errors + \",\\n\");\n                            out.append(\"\\\"unknown\\\": \" + unknown + \"\\n\");\n                        }\n                    });\n                    out.append(\"}\");\n                    out.flush();\n                    outputStream.flush();\n                } catch (Exception err) {\n                    log.error().exception(err).log(\"error\");\n                    throw new RuntimeException(err);\n                }\n            };\n            return Response.ok(output).type(MediaType.APPLICATION_JSON_TYPE).build();\n        } catch (Throwable err) {\n            log.error()\n                    .attr(\"namespace\", namespaceName)\n                    .exception(err)\n                    .log(\"Error while scanning offloaded ledgers for namespace\");\n            throw new RestException(Response.Status.INTERNAL_SERVER_ERROR,\n                    \"Error while scanning ledgers for \" + namespaceName);\n        }\n    }\n\n    @GET\n    @Path(\"/{tenant}/{namespace}/entryFilters\")\n    @Operation(summary = \"Get maxConsumersPerSubscription config on a namespace.\")\n    @ApiResponses(value = {\n            @ApiResponse(responseCode = \"200\", description = \"Get maxConsumersPerSubscription config on a namespace.\",\n                    content = @Content(schema = @Schema(implementation = EntryFilters.class))),\n            @ApiResponse(responseCode = \"403\", description = \"Don't have admin permission\"),\n            @ApiResponse(responseCode = \"404\", description = \"Namespace does not exist\") })\n    public void getEntryFiltersPerTopic(\n            @Suspended final AsyncResponse asyncResponse,\n            @PathParam(\"tenant\") String tenant,\n            @PathParam(\"namespace\") String namespace) {\n        validateNamespaceName(tenant, namespace);\n        validateNamespacePolicyOperationAsync(namespaceName, PolicyName.ENTRY_FILTERS, PolicyOperation.READ)","sourceCodeStart":3613,"sourceCodeEnd":3649,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/Namespaces.java#L3613-L3649","documentation":"Top-level error handler of the namespace offloaded-ledger scan endpoint: any Throwable escaping while preparing or running the scan is converted into HTTP 500 with message 'Error while scanning ledgers for <namespace>'. Unlike the streaming-lambda case, this fires before/beside streaming and gives the caller a clean (but opaque) 500 with the namespace name.","triggerScenarios":"GET /admin/v2/namespaces/{tenant}/{namespace}/tiDBLedgers when the initial scan setup fails — typically inability to read ledgers from the metadata service, authorization failure, or metadata inconsistency for the namespace.","commonSituations":"BookKeeper metadata service (ZooKeeper) unreachable or session expired; ledgers referenced by topics already deleted from metadata; offload driver misconfiguration; insufficient permissions on the namespace.","solutions":["Check the broker log for 'Error while scanning offloaded ledgers for namespace' to get the wrapped root-cause stack trace.","Verify the BookKeeper/metadata service (e.g. ZooKeeper) is healthy and reachable from the broker.","Confirm the requesting user has superuser/namespace read permissions and that the namespace exists; then retry the scan."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-check permissions and namespace existence before scanning\nadmin.namespaces().getPolicies(tenant + \"/\" + namespace); // throws 403/404 early if unavailable","typeGuard":null,"tryCatchPattern":"try {\n    return admin.namespaces().getTiDBLedgers(tenant, namespace);\n} catch (PulsarAdminException e) {\n    log.error(\"Offloaded ledger scan failed for {}/{}: {}\", tenant, namespace, e.getMessage());\n    // check broker-side root cause: metadata service health, offload config, permissions\n    throw e;\n}","preventionTips":["Monitor ZooKeeper/metadata service health; most 500s here stem from metadata read failures.","Grant the caller superuser or adequate namespace read permissions before scanning.","Grep broker logs for 'Error while scanning offloaded ledgers for namespace' to identify the wrapped cause."],"tags":["pulsar","admin-api","rest-exception","offloading","metadata"],"backgroundTag":"ledger-scan-failed","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"}