apache/pulsar · error · PulsarAdminException
Invalid message id (must be in format: ledgerId:entryId) val
Error message
Invalid message id (must be in format: ledgerId:entryId) value ${resetMessageIdStr} What it means
CliCommand.validateMessageIdString parses a message id string that must be exactly 'ledgerId:entryId' (two colon-separated longs), optionally attaching a partition index. Guava Preconditions.checkArgument and Long.parseLong failures are caught and rethrown as PulsarAdminException with the offending value echoed, so any malformed input lands here.
Source
Thrown at pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CliCommand.java:79
static String validateNonPersistentTopic(String topic) {
TopicName topicName = TopicName.get(topic);
if (topicName.getDomain() != TopicDomain.non_persistent) {
throw new IllegalArgumentException("Need to provide a non-persistent topic name");
}
return topicName.toString();
}
static MessageId validateMessageIdString(String resetMessageIdStr) throws PulsarAdminException {
return validateMessageIdString(resetMessageIdStr, -1);
}
static MessageId validateMessageIdString(String resetMessageIdStr, int partitionIndex) throws PulsarAdminException {
String[] messageId = resetMessageIdStr.split(":");
try {
com.google.common.base.Preconditions.checkArgument(messageId.length == 2);
return new MessageIdImpl(Long.parseLong(messageId[0]), Long.parseLong(messageId[1]), partitionIndex);
} catch (Exception e) {
throw new PulsarAdminException(
"Invalid message id (must be in format: ledgerId:entryId) value " + resetMessageIdStr);
}
}
Set<AuthAction> getAuthActions(List<String> actions) {
Set<AuthAction> res = new TreeSet<>();
AuthAction authAction;
for (String action : actions) {
try {
authAction = AuthAction.valueOf(action);
} catch (IllegalArgumentException exception) {
throw new ParameterException(String.format("Illegal auth action '%s'. Possible values: %s",
action, Arrays.toString(AuthAction.values())));
}
res.add(authAction);
}
return res;View on GitHub (pinned to 820761864e)
Solutions
- Format the argument as exactly two colon-separated longs: ledgerId:entryId (e.g. 12:34)
- Strip extra components (partition index, batch index) from the copied message id before passing it
- Verify both parts are valid non-empty decimal longs with no whitespace
- If you have a MessageId object, serialize it yourself into 'ledgerId:entryId' rather than trusting toString() output
Example fix
// before --message-id 12:34:5 // after --message-id 12:34
Defensive patterns
Strategy: validation
Validate before calling
// Validate the message id string before passing it to the CLI
String mid = resetMessageIdStr.trim();
if (!mid.matches("\\d+:\\d+")) {
throw new IllegalArgumentException("message id must be ledgerId:entryId, got: " + resetMessageIdStr);
} Try / catch
try {
admin.topics().resetCursor(topic, subscription, messageId);
} catch (PulsarAdminException e) {
if (e.getMessage() != null && e.getMessage().contains("Invalid message id")) {
log.error("Fix format to ledgerId:entryId; input was: {}", resetMessageIdStr);
}
throw e;
} Prevention
- Always supply exactly two colon-separated longs: ledgerId:entryId
- Strip partition/batch suffixes from message ids copied from logs before reuse
- Store message ids for cursor resets in the normalized ledgerId:entryId form
- Regex-validate the input in wrapper scripts around pulsar-admin
When it happens
Trigger: Passing a reset-cursor or similar admin command a message id that is not ledgerId:entryId — e.g. '123:45:67', 'abc:def', '123-45', an empty string, or a MessageId.toString() variant with extra components like 'ledgerId:entryId:partitionIndex'.
Common situations: Copy-pasting a message id from logs that includes extra fields; using a broker's verbose message id format with batch index or partition suffix; typos in manual cursor-reset operations; using 'latest'/'earliest' special values where the command expects numeric ids.
Related errors
- Need to provide a persistent topic name
- Need to provide a non-persistent topic name
- unable to parse namespaces parameter list:
- unable to parse primary parameter list:
- Unknown auto failover policy params specified :
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/ad9e251094a5094d.
Report an issue: GitHub.