apache/seatunnel · error · PulsarConnectorException

CommonErrorCodeDeprecated.UNSUPPORTED_OPERATION

CommonErrorCodeDeprecated.UNSUPPORTED_OPERATION

Error message

No consumer metadata found for table path '%s'

What it means

PulsarSplitEnumerator.createPulsarPartitionSplit looks up the PulsarConsumerMetadata for the table that owns a TopicPartition when materializing splits. If no metadata is registered for the resolved TablePath, it throws UNSUPPORTED_OPERATION with this message. It indicates internal state inconsistency: the enumerator is assigning splits for a topic whose table was never initialized.

Solutions

  1. Ensure every topic matched by topic-pattern is covered by a configured table entry with consumer metadata.
  2. Restrict topic-pattern so newly created topics are not picked up by the enumerator (or recreate the job so metadata includes them).
  3. Discard stale checkpoints/savepoints taken with a different topic/table configuration and restart the job fresh.
  4. Report as a bug if it occurs with a stable single-table config — this path normally indicates an internal invariant violation.

Example fix

// before
topic-pattern = "persistent://public/default/.+"
// after (narrow the pattern so only configured topics match)
topic-pattern = "persistent://public/default/my-topic.*"
Defensive patterns

Strategy: try-catch

Validate before calling

if (cfg.getOptional("topic-pattern").isPresent())
    verifyPatternOnlyMatchesConfiguredTables(cfg.getString("topic-pattern"), cfg.getOptional("topic"));

Try / catch

try {
    enumerator.assignSplits();
} catch (PulsarConnectorException e) {
    if (String.valueOf(e.getMessage()).contains("No consumer metadata found")) {
        // rescale/restart with a config covering the discovered topic, or drop stale checkpoints
    }
    throw e;
}

Prevention

When it happens

Trigger: A TopicPartition arrives (e.g. from topic discovery or addSplitsBack) whose resolved TablePath is absent from consumerMetadataMap — e.g. topics discovered by pattern that were not registered during startup, or state deserialized from a checkpoint that predates a table's metadata.

Common situations: Topic-pattern discovery picking up new topics at runtime after metadata was built; restoring a job from an old checkpoint after changing the config's topic list; multi-table configs where a discovered topic maps to no configured table.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/a88396a2a7f8b2d2. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-pulsar/src/main/java/org/apache/seatunnel/connectors/seatunnel/pulsar/source/enumerator/PulsarSplitEnumerator.java:187

            LOG.debug("Partition discovery is disabled.");
            noMoreNewPartitionSplits = true;
        }
        if (newPartitions.isEmpty()) {
            return;
        }
        List<PulsarPartitionSplit> newSplits =
                newPartitions.stream()
                        .map(this::createPulsarPartitionSplit)
                        .collect(Collectors.toList());
        addPartitionSplitChangeToPendingAssignments(newSplits);
        assignPendingPartitionSplits(context.registeredReaders());
    }

    private PulsarPartitionSplit createPulsarPartitionSplit(TopicPartition partition) {
        TablePath tablePath = resolveTablePath(partition);
        PulsarConsumerMetadata consumerMetadata = consumerMetadataMap.get(tablePath);
        if (consumerMetadata == null) {
            throw new PulsarConnectorException(
                    CommonErrorCodeDeprecated.UNSUPPORTED_OPERATION,
                    String.format("No consumer metadata found for table path '%s'", tablePath));
        }
        StopCursor partitionStopCursor = consumerMetadata.getStopCursor().copy();
        PulsarPartitionSplit split =
                new PulsarPartitionSplit(partition, partitionStopCursor, null, tablePath);
        if (partitionStopCursor instanceof LatestMessageStopCursor) {
            ((LatestMessageStopCursor) partitionStopCursor).prepare(pulsarAdmin, partition);
        }
        if (consumerMetadata.getStartCursor() instanceof SubscriptionStartCursor) {
            ((SubscriptionStartCursor) consumerMetadata.getStartCursor())
                    .ensureSubscription(
                            consumerMetadata.getConsumerConfig().getSubscriptionName(),
                            partition,
                            pulsarAdmin);
        }
        return split;
    }

View on GitHub (pinned to cf67b549a7)