apache/pulsar · error · MetadataStoreException

Expected target metadata store to be Oxia

Error message

Expected target metadata store to be Oxia

What it means

MigrationCoordinator migrates metadata from a source store to a target store. The PIP-462 migration tooling only supports Oxia as the target, so the constructor validates that the target URL starts with "oxia://" and otherwise throws MetadataStoreException with this message before creating the Oxia client.

Source

Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/coordination/impl/MigrationCoordinator.java:76

    private final Duration preparationTimeout;

    private static final int MAX_PENDING_OPS = 1000;
    private static final Duration DEFAULT_PREPARATION_TIMEOUT = Duration.ofSeconds(60);

    public MigrationCoordinator(MetadataStore sourceStore, String targetUrl) throws MetadataStoreException {
        this(sourceStore, targetUrl, DEFAULT_PREPARATION_TIMEOUT);
    }

    @VisibleForTesting
    public MigrationCoordinator(MetadataStore sourceStore, String targetUrl, Duration preparationTimeout)
            throws MetadataStoreException {
        this.sourceStore = sourceStore;
        this.targetUrl = targetUrl;
        this.preparationTimeout = preparationTimeout;
        this.migrationStateCache = sourceStore.getMetadataCache(MigrationState.class);

        if (!targetUrl.startsWith("oxia://")) {
            throw new MetadataStoreException("Expected target metadata store to be Oxia");
        }

        this.oxiaClient = new OxiaMetadataStoreProvider().getOxiaClient(targetUrl);
    }

    /**
     * Start the migration process.
     *
     * @throws Exception if migration fails
     */
    public void startMigration() throws Exception {
        log.info("=== Starting Migration ===");
        log.info().attr("source", sourceStore.getClass().getSimpleName()).log("Source (current)");
        log.info().attr("target", targetUrl).log("Target");

        // 1. Create migration flag. If another migration is already in progress, this fails without
        // affecting the existing migration state.
        setInitialMigrationPhase();

View on GitHub (pinned to 820761864e)

Solutions

  1. Set the migration target URL to an "oxia://host:port" style address
  2. Correct typos in the URL scheme (must be exactly "oxia://")
  3. If you intended to migrate to another backend, use a migration path that targets Oxia, then move off Oxia separately

Example fix

// before
new MigrationCoordinator(sourceStore, "zk://zk1:2181/metadata", timeout);
// after
new MigrationCoordinator(sourceStore, "oxia://oxia1:6648", timeout);
Defensive patterns

Strategy: validation

Validate before calling

// Java
if (targetUrl == null || !targetUrl.startsWith("oxia://")) {
    throw new IllegalArgumentException("Migration target must be an oxia:// URL, got: " + targetUrl);
}

Type guard

boolean isOxiaTarget(String url) {
    return url != null && url.startsWith("oxia://");
}

Try / catch

try {
    coordinator = new MigrationCoordinator(sourceStore, targetUrl, timeout);
} catch (MetadataStoreException e) {
    // fix targetUrl to oxia:// scheme before retrying
}

Prevention

When it happens

Trigger: Constructing MigrationCoordinator with a targetUrl that does not begin with "oxia://" — e.g. "zk://...", "rocksdb://...", or a mistyped Oxia URL missing the scheme.

Common situations: Configuring a metadata migration with a ZooKeeper target by mistake; copying a target URL from older tooling predating Oxia-only targets; typo like "oxia:/host" (single slash).

Related errors


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