{"record":{"id":"98a5516a55d79b5e","repo":"apache/pulsar","slug":"timeout-during-close-operation","errorCode":null,"errorMessage":"Timeout during close operation","messagePattern":"Timeout during close operation","errorType":"exception","errorClass":"ManagedLedgerException","httpStatus":null,"severity":"error","filePath":"managed-ledger/src/main/java/org/apache/bookkeeper/mledger/impl/ManagedCursorImpl.java","lineNumber":2911,"sourceCode":"        final Result result = new Result();\n        final CountDownLatch latch = new CountDownLatch(1);\n        asyncClose(new AsyncCallbacks.CloseCallback() {\n            @Override\n            public void closeComplete(Object ctx) {\n                log.debug(\"Successfully closed ledger\");\n                latch.countDown();\n            }\n\n            @Override\n            public void closeFailed(ManagedLedgerException exception, Object ctx) {\n                log.warn().exception(exception).log(\"Closing ledger failed\");\n                result.exception = exception;\n                latch.countDown();\n            }\n        }, null);\n\n        if (!latch.await(ManagedLedgerImpl.AsyncOperationTimeoutSeconds, TimeUnit.SECONDS)) {\n            throw new ManagedLedgerException(\"Timeout during close operation\");\n        }\n\n        if (result.exception != null) {\n            throw result.exception;\n        }\n    }\n\n    /**\n     * Persist given markDelete position to cursor-ledger or zk-metaStore based on max number of allowed unack-range\n     * that can be persist in zk-metastore. If current unack-range is higher than configured threshold then broker\n     * persists mark-delete into cursor-ledger else into zk-metastore.\n     *\n     * @param position\n     * @param properties\n     * @param callback\n     * @param ctx\n     */\n    void persistPositionWhenClosing(Position position, Map<String, Long> properties,","sourceCodeStart":2893,"sourceCodeEnd":2929,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/managed-ledger/src/main/java/org/apache/bookkeeper/mledger/impl/ManagedCursorImpl.java#L2893-L2929","documentation":"The shared VALIDATION lambda applied to generic jcloud drivers requires at least one of region (managedLedgerOffloadRegion) or service endpoint (managedLedgerOffloadServiceEndpoint) to identify the storage service, and throws IllegalArgumentException when both are empty. The message includes the configured driver name so you can see which provider failed validation.","triggerScenarios":"getBlobStore/initiating offload with a driver using the common VALIDATION (e.g. aws, gcs, azureblob) while both TieredStorageConfiguration.getRegion() and getServiceEndpoint() are null/empty.","commonSituations":"Omitting managedLedgerOffloadRegion when using AWS S3, forgetting managedLedgerOffloadServiceEndpoint for S3-compatible endpoints (MinIO, COS, BOS), property placed in the wrong config file, or topic-level offload policy missing the region field.","solutions":["Set managedLedgerOffloadRegion=<region> (e.g. us-west-2) for regional cloud providers.","For S3-compatible storage without a region, set managedLedgerOffloadServiceEndpoint=<endpoint-url> instead.","Confirm the properties are read by the broker/offloader (right conf file, not shadowed by an empty override)."],"exampleFix":"// before: broker.conf\nmanagedLedgerOffloadDriver=s3\nmanagedLedgerOffloadBucket=my-bucket\n\n// after: region supplied\nmanagedLedgerOffloadDriver=s3\nmanagedLedgerOffloadBucket=my-bucket\nmanagedLedgerOffloadRegion=us-west-2","handlingStrategy":"validation","validationCode":"boolean hasRegion = config.getRegion() != null && !config.getRegion().isEmpty();\nboolean hasEndpoint = config.getServiceEndpoint() != null && !config.getServiceEndpoint().isEmpty();\nif (!hasRegion && !hasEndpoint) {\n    throw new IllegalStateException(\"Set managedLedgerOffloadRegion or managedLedgerOffloadServiceEndpoint for driver \" + config.getDriver());\n}","typeGuard":null,"tryCatchPattern":"try {\n    provider.validate(tieringConfig);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Either Region or ServiceEndpoint\")) {\n        log.error(\"Configure managedLedgerOffloadRegion (cloud) or managedLedgerOffloadServiceEndpoint (S3-compatible) for {}\", tieringConfig.getDriver());\n    }\n    throw e;\n}","preventionTips":["For S3-compatible stores (MinIO/COS/Ceph), always set managedLedgerOffloadServiceEndpoint.","For regional clouds, always set managedLedgerOffloadRegion.","Validate broker.conf with a startup script before rolling out changes.","Keep a per-driver checklist of required managedLedgerOffload* properties."],"tags":["configuration","validation","offload","region"],"backgroundTag":"missing-config-property","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}