apache/pulsar · error · IllegalArgumentException

--start-message-id must be 'latest' or 'earliest'; the '<led

Error message

--start-message-id must be 'latest' or 'earliest'; the '<ledgerId>:<entryId>' form is not supported by this version of pulsar-client.

What it means

This V5-based pulsar-client CLI does not support numeric MessageId (ledgerId:entryId) start positions for the read command. Only the symbolic values 'latest' and 'earliest' are accepted; anything else throws IllegalArgumentException and the command exits.

Source

Thrown at pulsar-client-tools/src/main/java/org/apache/pulsar/client/cli/CmdRead.java:128

    private boolean printMetadata = false;

    public CmdRead() {
        // Do nothing
        super();
    }

    /**
     * Run the read command.
     *
     * @return 0 for success, < 0 otherwise
     */
    public int run() throws PulsarClientException, IOException {
        if (this.numMessagesToRead < 0) {
            throw (new IllegalArgumentException("Number of messages should be zero or positive."));
        }
        if (!START_LATEST.equals(startMessageId) && !START_EARLIEST.equals(startMessageId)) {
            throw new IllegalArgumentException("--start-message-id must be 'latest' or 'earliest'; the "
                    + "'<ledgerId>:<entryId>' form is not supported by this version of pulsar-client.");
        }

        if (this.serviceURL.startsWith("ws")) {
            return readFromWebSocket(topic);
        } else {
            return read(topic);
        }
    }

    private int read(String topic) {
        int numMessagesRead = 0;
        int returnCode = 0;

        final Schema<?> schema;
        if ("auto_consume".equals(schemaType)) {
            schema = Schema.autoConsume();
        } else if ("bytes".equals(schemaType)) {
            schema = Schema.bytes();

View on GitHub (pinned to 820761864e)

Solutions

  1. Use --start-message-id latest or --start-message-id earliest.
  2. If you need an exact position, use the full Java client Reader with MessageId, or the admin/reader APIs in a non-V5 client.
  3. Strip any numeric ID formatting from your script and map it to 'latest'/'earliest' semantics.

Example fix

// before
pulsar-client read my-topic --start-message-id 1287:43
// after
pulsar-client read my-topic --start-message-id latest
Defensive patterns

Strategy: validation

Validate before calling

// bash: only symbolic positions allowed
case "$START_ID" in latest|earliest) ;; *) echo "use latest or earliest, got: $START_ID"; exit 1;; esac

Type guard

function isValidStartMessageId(v) { return v === 'latest' || v === 'earliest'; }

Try / catch

try { readCmd(startId); } catch (IllegalArgumentException e) { if (e.getMessage().includes("--start-message-id")) { /* fall back to 'latest' */ } else throw e; }

Prevention

When it happens

Trigger: Running `pulsar-client read <topic> --start-message-id '12:3'` or any '<ledgerId>:<entryId>' string instead of 'latest'/'earliest'.

Common situations: Porting scripts written against the full pulsar-client where numeric message IDs were supported; users copying a MessageId from broker logs or admin output; automation that formats the position from a previous read.

Related errors


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