apache/pulsar · info · RestException

Message not found

Error message

Message not found

What it means

When generating the HTTP response for a peeked entry, the broker catches a NullPointerException thrown while constructing the response (e.g. the entry payload/metadata was null or already released) and converts it into a 404 NOT_FOUND RestException with message 'Message not found'. It signals that although a peek was attempted, no retrievable message exists at the requested position.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java:3110

                        "Peek messages on a non-persistent topic is not allowed");
            } else {
                if (subName.startsWith(((PersistentTopic) topic).getReplicatorPrefix())) {
                    PersistentReplicator repl = getReplicatorReference(subName, (PersistentTopic) topic);
                    entry = repl.peekNthMessage(messagePosition);
                } else {
                    entry = findOrCreateSubscriptionAsync(subName, (PersistentTopic) topic)
                            .thenCompose(sub -> sub.peekNthMessage(messagePosition));
                }
            }
            return entry.thenApply(e -> Pair.of(e, (PersistentTopic) topic));
        }).thenCompose(entryTopicPair -> {
            Entry entry = entryTopicPair.getLeft();
            PersistentTopic persistentTopic = entryTopicPair.getRight();
            try {
                Response response = generateResponseWithEntry(entry, persistentTopic);
                return CompletableFuture.completedFuture(response);
            } catch (NullPointerException npe) {
                throw new RestException(Status.NOT_FOUND, "Message not found");
            } catch (Exception exception) {
                log.error()
                        .attr("position", messagePosition)
                        .attr("topic", topicName)
                        .attr("subscription", subName)
                        .exception(exception)
                        .log("Failed to peek message");
                throw new RestException(exception);
            } finally {
                if (entry != null) {
                    entry.release();
                }
            }
        });
    }

    protected CompletableFuture<Response> internalExamineMessageAsync(String initialPosition, long messagePosition,
                                                                      boolean authoritative) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Retry the peek; transient races often clear on the next attempt
  2. Validate the position is within the topic's retained entry range (getNumberOfEntries / stats) before peeking
  3. Check message TTL and retention policies if entries disappear quickly

Example fix

// before
Response r = admin.topics().peekNthMessage(topic, "sub", 1_000_000);
// after
long total = admin.topics().getStats(topic).getNumberOfEntries();
if (position < total) { Response r = admin.topics().peekNthMessage(topic, "sub", (int) position); }
Defensive patterns

Strategy: retry

Validate before calling

// check position is within retained range
TopicStats stats = admin.topics().getStats(topic);
if (position >= stats.getNumberOfEntries()) throw new IllegalArgumentException("position out of range");

Try / catch

try { admin.topics().peekNthMessage(topic, sub, position); }
catch (PulsarAdminException e) {
    if (e.getStatusCode() == 404) { /* message gone: rescan or skip */ }
}

Prevention

When it happens

Trigger: generateResponseWithEntry(null/invalid entry) inside the peek path; concurrent cursor advancement or retention deleting the entry between lookup and response generation; requesting a position beyond the retained range.

Common situations: Peeking with a large position on a topic with fewer entries; message expiry/compaction removing the entry mid-request; race between a consumer ack and an admin peek.

Related errors


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