apache/pulsar · error · CommandLine.ParameterException

Please supply message content with either --messages or --fi

Error message

Please supply message content with either --messages or --files

What it means

CmdProduce.run() validates that the producer was given content before creating a client. picocli option parsing allows invoking `pulsar-client produce` with neither --messages (-m) nor --files (-f); because that would silently send nothing, the command throws a CommandLine.ParameterException, which picocli prints as a usage error.

Source

Thrown at pulsar-client-tools/src/main/java/org/apache/pulsar/client/cli/CmdProduce.java:256

    /**
     * Run the producer.
     *
     * @return 0 for success, < 0 otherwise
     * @throws Exception
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public int run() throws PulsarClientException {
        if (this.numTimesProduce <= 0) {
            throw new CommandLine.ParameterException(commandSpec.commandLine(),
                    "Number of times need to be positive number.");
        }

        if (messages.size() > 0) {
            messages = messages.stream().map(str -> str.split(separator)).flatMap(Stream::of).toList();
        }

        if (messages.size() == 0 && messageFileNames.size() == 0) {
            throw new CommandLine.ParameterException(commandSpec.commandLine(),
                    "Please supply message content with either --messages or --files");
        }

        if (keyValueEncodingType == null) {
            keyValueEncodingType = KEY_VALUE_ENCODING_TYPE_NOT_SET;
        } else if (!KEY_VALUE_ENCODING_TYPE_NOT_SET.equals(keyValueEncodingType)) {
            // KeyValue schemas are not yet supported by the V5-based pulsar-client.
            throw new IllegalArgumentException("KeyValue schemas (--key-value-encoding-type) are not "
                    + "supported by this version of pulsar-client; produce with a plain value schema "
                    + "(-vs bytes|string|avro:<def>|json:<def>) instead.");
        }

        int totalMessages = (messages.size() + messageFileNames.size()) * numTimesProduce;
        if (totalMessages > MAX_MESSAGES) {
            String msg = "Attempting to send " + totalMessages + " messages. Please do not send more than "
                    + MAX_MESSAGES + " messages";
            throw new IllegalArgumentException(msg);
        }

View on GitHub (pinned to 820761864e)

Solutions

  1. Pass message content: add --messages/-m with one or more strings, e.g. -m 'hello' -m 'world'.
  2. Pass file content instead: add --files/-f pointing to file(s) whose bytes become the message body.
  3. Check that the variable feeding -m is non-empty in your script (e.g. : "${MSG:?empty}" in bash).
  4. If you intended multiple values, keep them separated by the configured separator so the split produces a non-empty list.

Example fix

// before
pulsar-client produce my-topic --url ...
// after
pulsar-client produce my-topic --url ... -m 'hello'
Defensive patterns

Strategy: validation

Validate before calling

// bash: fail fast before invoking the CLI
: "${MSG:?MSG must be non-empty}"
[ -n "$MSG" ] || { echo 'provide --messages or --files'; exit 1; }

Type guard

function hasProduceContent(msgs, files) { return (Array.isArray(msgs) && msgs.length > 0) || (Array.isArray(files) && files.length > 0); }

Prevention

When it happens

Trigger: Running `pulsar-client produce <topic>` with neither --messages nor --files, or with options whose values are empty (e.g. -m '' resolves to an empty list after splitting on the separator).

Common situations: Scripted/CI invocations where message content comes from a variable that is empty; forgetting -m/-f because the shell command was copied from a WebSocket or producer-args variant; quoting bugs that make the shell drop the argument.

Related errors


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