{"record":{"id":"52c15e3fa10851c6","repo":"apache/pulsar","slug":"publishtxnmessage-is-not-supported-by-non-persiste","errorCode":null,"errorMessage":"PublishTxnMessage is not supported by non-persistent topic","messagePattern":"PublishTxnMessage is not supported by non-persistent topic","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"warning","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentTopic.java","lineNumber":1330,"sourceCode":"                return checkSchemaCompatibleForConsumer(schema)\n                        .exceptionally(ex -> {\n                            Throwable realCause = FutureUtil.unwrapCompletionException(ex);\n                            if (realCause instanceof NotExistSchemaException) {\n                                throw FutureUtil.wrapToCompletionException(\n                                        new IncompatibleSchemaException(\"Failed to add schema to an active topic\"\n                                                + \" with empty(BYTES) schema: new schema type \" + schema.getType()));\n                            }\n                            throw FutureUtil.wrapToCompletionException(realCause);\n                        });\n            } else {\n                return addSchema(schema).thenCompose(schemaVersion -> CompletableFuture.completedFuture(null));\n            }\n        });\n    }\n\n    @Override\n    public void publishTxnMessage(TxnID txnID, ByteBuf headersAndPayload, PublishContext publishContext) {\n        throw new UnsupportedOperationException(\"PublishTxnMessage is not supported by non-persistent topic\");\n    }\n\n    @Override\n    public CompletableFuture<Void> endTxn(TxnID txnID, int txnAction, long lowWaterMark) {\n        return FutureUtil.failedFuture(\n                new Exception(\"Unsupported operation endTxn in non-persistent topic.\"));\n    }\n\n    @Override\n    public CompletableFuture<Void> truncate() {\n        return FutureUtil.failedFuture(new NotAllowedException(\"Unsupported truncate\"));\n    }\n\n    protected boolean isTerminated() {\n        return false;\n    }\n\n","sourceCodeStart":1312,"sourceCodeEnd":1348,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/nonpersistent/NonPersistentTopic.java#L1312-L1348","documentation":"NonPersistentTopic.publishTxnMessage unconditionally throws UnsupportedOperationException: transactional message publishing requires durable state (pending acks, txn markers) that non-persistent topics cannot maintain, so transactions are unsupported on them.","triggerScenarios":"Producing a transactional message (transaction.newBuilder().send(...) via producer) to a non-persistent topic; endTxn on a non-persistent topic likewise fails with a failed future.","commonSituations":"Application configured with transactions enabled but producers targeting non-persistent topics; framework/messaging abstraction picking non-persistent topic while using Pulsar transactions; tests mixing transaction features with non-persistent topics.","solutions":["Use persistent topics for transactional producers","Route transactional sends to persistent topics only; check topic type before beginTransaction/send","Disable transactions for producers bound to non-persistent topics","Catch UnsupportedOperationException and fall back to non-transactional publish"],"exampleFix":"// before\nTransaction txn = client.newTransaction().build();\nnonPersistentProducer.newMessage(txn).send();\n// after\nProducer persistentProducer = client.newProducer()\n    .topic(\"persistent://public/default/txn-topic\").create();\npersistentProducer.newMessage(txn).send();","handlingStrategy":"type-guard","validationCode":"if (!topicName.getPersistent()) {\n    // route through a non-transactional producer instead\n    return producer.newMessage(value).send();\n}","typeGuard":"boolean supportsTxnPublish(String topic) {\n    return topic.startsWith(\"persistent://\");\n}","tryCatchPattern":"try {\n    producer.newMessage(txn).send();\n} catch (UnsupportedOperationException e) {\n    log.warn(\"Txn publish unsupported on non-persistent topic; sending non-txn\");\n}","preventionTips":["Only use transactions with persistent topics","Document topic-type constraints in team conventions","Gate transactional code paths on topic type in messaging abstractions"],"tags":["java","broker","non-persistent","transactions","unsupported-operation"],"backgroundTag":"operation-not-supported-on-non-persistent-topic","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"}