apache/pulsar · error · ManagedLedgerException

Timeout during managed ledger terminate

Error message

Timeout during managed ledger terminate

What it means

S3_VALIDATION is applied to the S3 family of drivers and requires managedLedgerOffloadServiceEndpoint to be set explicitly; it throws this IllegalArgumentException when getServiceEndpoint() is empty. Unlike the generic validation, the S3-specific check insists on an explicit service endpoint (custom endpoint for S3-compatible stores) before anything else.

Source

Thrown at managed-ledger/src/main/java/org/apache/bookkeeper/mledger/impl/ManagedLedgerImpl.java:1596

        final Result result = new Result();

        asyncTerminate(new TerminateCallback() {
            @Override
            public void terminateComplete(Position lastPosition, Object ctx) {
                result.lastPosition = lastPosition;
                counter.countDown();
            }

            @Override
            public void terminateFailed(ManagedLedgerException exception, Object ctx) {
                result.exception = exception;
                counter.countDown();
            }

        }, null);

        if (!counter.await(AsyncOperationTimeoutSeconds, TimeUnit.SECONDS)) {
            throw new ManagedLedgerException("Timeout during managed ledger terminate");
        }

        if (result.exception != null) {
            log.error().exception(result.exception).log("Error terminating managed ledger");
            throw result.exception;
        }

        return result.lastPosition;
    }

    @Override
    public boolean isTerminated() {
        return state == State.Terminated;
    }

    @Override
    public boolean isMigrated() {
        return migrated;

View on GitHub (pinned to 820761864e)

Solutions

  1. Set managedLedgerOffloadServiceEndpoint=http(s)://<host>:<port> to your S3-compatible endpoint in broker.conf.
  2. Then also supply managedLedgerOffloadBucket (the next check) and managedLedgerOffloadRegion if your provider needs it.
  3. Confirm the broker/offloader picks up the property (correct conf file, restarted process, no empty override).
  4. For real AWS S3, prefer a driver variant that doesn't require an explicit endpoint if you don't have a custom one.

Example fix

// before: broker.conf
managedLedgerOffloadDriver=s3
managedLedgerOffloadBucket=minio-bucket

// after: endpoint added
managedLedgerOffloadDriver=s3
managedLedgerOffloadBucket=minio-bucket
managedLedgerOffloadServiceEndpoint=http://minio.internal:9000
Defensive patterns

Strategy: validation

Validate before calling

if (config.getServiceEndpoint() == null || config.getServiceEndpoint().isEmpty()) {
    throw new IllegalStateException("managedLedgerOffloadServiceEndpoint must be set for driver " + config.getDriver());
}
new java.net.URI(config.getServiceEndpoint()); // must be a valid endpoint URI

Try / catch

try {
    provider.validate(tieringConfig);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("ServiceEndpoint must specified")) {
        log.error("Set managedLedgerOffloadServiceEndpoint=http(s)://host:port for S3-compatible offload");
    }
    throw e;
}

Prevention

When it happens

Trigger: Using an S3-driver (driver value validated with S3_VALIDATION) and initializing offload while managedLedgerOffloadServiceEndpoint is null/empty in TieredStorageConfiguration.

Common situations: Offloading to MinIO/Ceph/COS/other S3-compatible storage without setting managedLedgerOffloadServiceEndpoint, endpoint URL typo'd or defined under a wrong property name, or config file not reloaded after adding the endpoint.

Understand the failure class

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/9d9de6789a9de170. Report an issue: GitHub.