apache/seatunnel · error · PulsarConnectorException
PulsarConnectorErrorCode.GET_LAST_CURSOR_FAILED
PulsarConnectorErrorCode.GET_LAST_CURSOR_FAILED
Error message
Failed to get the last cursor
What it means
LatestMessageStopCursor.prepare fetches the topic's last message ID via the PulsarAdmin client so the split knows where to stop. If admin.topics().getLastMessageId(topic) throws a PulsarAdminException, it is wrapped as GET_LAST_CURSOR_FAILED with this message. Reading fails at split-prepare time because the stop position cannot be determined.
Source
Thrown at seatunnel-connectors-v2/connector-pulsar/src/main/java/org/apache/seatunnel/connectors/seatunnel/pulsar/source/enumerator/cursor/stop/LatestMessageStopCursor.java:46
import org.apache.pulsar.client.api.MessageId;
/**
* A stop cursor that initialize the position to the latest message id. The offsets initialization
* are taken care of by the {@code PulsarPartitionSplitReaderBase} instead of by the {@code
* PulsarSourceEnumerator}.
*/
public class LatestMessageStopCursor implements StopCursor {
private static final long serialVersionUID = 1L;
private MessageId messageId;
public void prepare(PulsarAdmin admin, TopicPartition partition) {
if (messageId == null) {
String topic = partition.getFullTopicName();
try {
messageId = admin.topics().getLastMessageId(topic);
} catch (PulsarAdminException e) {
throw new PulsarConnectorException(
PulsarConnectorErrorCode.GET_LAST_CURSOR_FAILED,
"Failed to get the last cursor",
e);
}
}
}
@Override
public boolean shouldStop(Message<?> message) {
MessageId id = message.getMessageId();
return id.compareTo(messageId) >= 0;
}
@Override
public StopCursor copy() {
return new LatestMessageStopCursor();
}
}View on GitHub (pinned to cf67b549a7)
Solutions
- Verify admin.service-url and Pulsar admin credentials are correct and reachable from the worker.
- Confirm the topic exists and the configured topic name matches exactly (including persistent:// domain/tenant/namespace/topic).
- Check broker logs for the underlying PulsarAdminException cause (TopicNotFound, NotAuthorized, etc.).
- For partitioned topics, ensure the partition reference used matches an existing partition.
Example fix
// before admin.service-url = "http://broker:8081" // after (correct admin port/service URL) admin.service-url = "http://broker:8080"
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: topic must exist and admin reachable admin.namespaces().getTopics(namespace).contains(fullTopicName);
Try / catch
try {
prepareStopCursor(admin, partition);
} catch (PulsarConnectorException e) {
if (e.getErrorCode() == PulsarConnectorErrorCode.GET_LAST_CURSOR_FAILED) {
// check cause: TopicNotFound -> fix topic name; auth -> fix credentials
}
throw e;
} Prevention
- Validate topic names exactly (persistent://tenant/namespace/topic).
- Confirm admin.service-url and credentials before running LATEST stop mode jobs.
- Pre-create topics so getLastMessageId never hits TopicNotFound.
When it happens
Trigger: Using stop.mode = LATEST when PulsarAdmin.topics().getLastMessageId fails for the full topic name — broker unreachable, topic does not exist, permission denied, or topic name (partitioned topic suffix) is malformed.
Common situations: Misconfigured admin.service-url or authentication; typo in topic name; reading a partitioned topic where the partition suffix handling mismatches; topic deleted between discovery and reader start.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Failed to close Pulsar admin.
- Failed to read AmazonDocumentDB data from database [%s], col
- PulsarConnectorErrorCode.PULSAR_AUTHENTICATION_FAILED
- You haven't enable transaction in Pulsar client.
- SeaTunnelAPIErrorCode.CONFIG_VALIDATION_FAILED
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/374843510a7c4622.
Report an issue: GitHub.