{"record":{"id":"582e134a0a481ad9","repo":"apache/pulsar","slug":"either-time-expiretime-or-message-position","errorCode":null,"errorMessage":"Either time (--expireTime) or message position (--position) has to be provided to expire messages","messagePattern":"Either time \\(--expireTime\\) or message position \\(--position\\) has to be provided to expire messages","errorType":"validation","errorClass":"ParameterException","httpStatus":null,"severity":"warning","filePath":"pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdTopics.java","lineNumber":903,"sourceCode":"        @Option(names = { \"-e\", \"--exclude-reset-position\" },\n                description = \"Exclude the reset position, start consume messages from the next position.\")\n        private boolean excludeResetPosition = false;\n\n        @Override\n        void run() throws PulsarAdminException {\n            if (expireTimeInSeconds >= 0 && isNotBlank(messagePosition)) {\n                throw new ParameterException(String.format(\"Can't expire message by time and \"\n                        + \"by message position at the same time.\"));\n            }\n            String topic = validateTopicName(topicName);\n            if (expireTimeInSeconds >= 0) {\n                getTopics().expireMessages(topic, subName, expireTimeInSeconds);\n            } else if (isNotBlank(messagePosition)) {\n                int partitionIndex = TopicName.get(topic).getPartitionIndex();\n                MessageId messageId = validateMessageIdString(messagePosition, partitionIndex);\n                getTopics().expireMessages(topic, subName, messageId, excludeResetPosition);\n            } else {\n                throw new ParameterException(\n                        \"Either time (--expireTime) or message position (--position) has to be provided\"\n                                + \" to expire messages\");\n            }\n        }\n    }\n\n    @Command(description = \"Expire messages that older than given expiry time (in seconds) \"\n            + \"for all subscriptions\")\n    private class ExpireMessagesForAllSubscriptions extends CliCommand {\n        @Parameters(description = \"persistent://tenant/namespace/topic\", arity = \"1\")\n        private String topicName;\n\n        @Option(names = {\"-t\", \"--expireTime\"}, description = \"Expire messages older than time in seconds \"\n                + \"(or minutes, hours, days, weeks eg: 100m, 3h, 2d, 5w)\", required = true,\n                converter = TimeUnitToSecondsConverter.class)\n        private Long expireTimeInSeconds;\n\n        @Override","sourceCodeStart":885,"sourceCodeEnd":921,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdTopics.java#L885-L921","documentation":"The expire-messages command requires at least one expiration criterion: either a relative time (--expireTime) or a message position (--position). If neither is provided, the command cannot determine what to expire and throws ParameterException.","triggerScenarios":"Running `pulsar-admin topics expire-messages <topic> -s <subscription>` with no --expireTime (or --expireTime < 0) and no --position.","commonSituations":"Forgetting that --expireTime must be a positive number of seconds (omitting it entirely); scripts where variables expand to empty; users expecting expiration to default to 'now'.","solutions":["Add --expireTime <seconds> to expire messages older than that duration","Or add --position <ledgerId:entryId> to expire up to a specific message position","Verify the script/variable supplying --expireTime is not empty or negative"],"exampleFix":"// before\npulsar-admin topics expire-messages my-topic -s sub1\n// after\npulsar-admin topics expire-messages my-topic -s sub1 --expireTime 3600","handlingStrategy":"validation","validationCode":"if ((expireTime == null || expireTime < 0) && (position == null || position.isBlank())) {\n    throw new IllegalArgumentException(\"Provide --expireTime or --position\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    admin.topics().expireMessages(topic, sub, expireSeconds);\n} catch (org.apache.pulsar.client.admin.PulsarAdminException e) {\n    log.error(\"expire-messages requires --expireTime or --position\", e);\n}","preventionTips":["Always supply --expireTime (positive seconds) or --position","Check script variables are non-empty before building the command","Remember neither flag has a default value"],"tags":["cli","parameter-validation","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}