Once a search has filled the Messages tab, the table gives you one line per message, and the pane below it shows the message you select in full: its key, its value, formatted as JSON, XML, text or hex, its headers, and the raw bytes Kafka stored. This page covers reading and copying what you've found. Which deserializer turns the bytes into text is covered in Deserialization & Formats.
orders messages, the newest selected, with the search form collapsed.- The message table: one row per message (The message table).
- The time zone of the Time column (Time zones).
- The detail pane's tabs for the selected message: Key, Message, Headers and Raw (The detail pane).
- Undock window: move the detail pane into a window of its own (Undocking the detail pane).
Select a row (click it, or move with the arrow keys) to show that message in the detail pane; until you do, the pane is greyed out. Drag the bar between the table and the pane to give either more room, and collapse the search form to give both more. Here a duplicated cluster tab, Storefront Dev (Consumers), keeps the cluster's consumer groups one click away while you read messages.
The message table
| Column | Shows |
|---|---|
| Offset | The message's offset in its partition. Offsets are numbered per partition, so the same offset appears once for each partition. |
| Partition | The partition the message is in. |
| Size | The serialized size: the key's and value's bytes as stored in Kafka, before deserialization
(headers not included). For example 86 bytes or 1.9 MB. |
| Time | The message's Kafka timestamp, to the millisecond, in the zone chosen in the column's header,
e.g. 2026-10-25 07:43:46.102 GMT. |
| Key | The deserialized key and value on one line: line breaks and repeated spaces are
squeezed out and only the first 200 characters are shown. A missing (null) key or value shows as
<null>, an empty one as <empty>. |
| Value (message) |
Rows come in the order of the search type, for example newest first for a Newest search (Search types). Click a column header to sort by it; click again to reverse. The Time column can't be sorted, and sorting is off while a live stream runs. Drag the column borders to widen a column.
The timestamp is whatever Kafka stored with the message: by default the time the producer created it, or the
time the broker appended it if the topic's message.timestamp.type is LogAppendTime.
The Raw tab says which.
Time zones
The drop-down in the Time header sets the zone the column is shown in. It starts at your computer's time zone; pick UTC to compare with broker logs, or the zone of the system that produced the messages.
The list has UTC and 27 common zones, grouped by region (the Americas, Africa, Asia, Europe and Oceania). If your
computer's zone isn't one of them, it's added at the top, as Europe/Dublin is here.
The offset in the list is the zone's standard one; the column shows the offset in force at each message's
time, so in summer America/New_York (GMT-05:00) shows times as
GMT-04:00.
The change applies at once, to the messages already in the table. Messages tabs you open afterwards start with the zone you picked last; when KafkIO restarts, it's your computer's zone again. The zone only affects this column: the date and time of an Occurring after/before search are always in your computer's zone, and the Raw tab shows UTC.
The detail pane
The Message tab is open by default. The tab you pick stays open as you move from message to message.
customer.- The message's partition and offset: what you need to find it again, for example with an Offset start search.
- The Schema Registry schema ID and type the value was decoded with, or
none(Schema IDs). - Search within the value (Searching within a message).
- Display as: how the value is shown (Display formats).
- View in Window: open the value in a window of its own (Opening a message in its own window).
The Key tab has the same bar and works the same way for the message's key. The text in both is read-only, with line numbers, and wraps to the pane's width. Select text and copy it with Ctrl+C (⌘+C on macOS), or right-click for Copy and Select All.
You see what was kept in memory: a key or value longer than the search's
Key/message trim ends with
...<Trimmed by KafkIO>. A value over 100 KB on a single line (no line breaks) is shown
without wrapping or colours, to keep KafkIO responsive.
Schema IDs
When a key or value was decoded with the Schema Registry deserializer, the bar shows
the schema's ID in the registry and its type (AVRO, JSON or PROTOBUF).
Here an Avro order on the orders-avro topic was written with schema ID 1 and is shown as JSON:
- Schema ID
1, typeAVRO: look the schema up under Schema Registry. - Decoded Avro, Protobuf and JSON Schema messages are shown as JSON.
With any other deserializer, both are none. Different messages on the same topic can carry
different schema IDs, for example after the schema evolved, so check the ID when two messages decode
differently.
Display formats
Each time you select a message, KafkIO looks at its key and value and picks how to show each one. You can change it with Display as; the next message you select is detected afresh.
| Display as | Picked when the text is | Shows |
|---|---|---|
| JSON | A JSON object or array | Pretty-printed and indented, with syntax colours. |
| XML | Well-formed XML | Pretty-printed and indented, with syntax colours. |
| STRING | Mostly printable text, or empty | The text as it is. |
| HEX (pre-deserialization) | Binary: mostly unprintable, or starting with a zero byte | A hex dump of the bytes as stored in Kafka (Hex view). |
JSON and XML are formatted for display only: a compact JSON message {"status":"NEW"} appears as
"status" : "NEW" on its own line, but the message itself is unchanged, and a
text filter matches it as it was sent. Choosing
JSON or XML for text that isn't valid JSON or XML (a
trimmed message, for example) shows it unformatted. STRING is useful to see a JSON
or XML message exactly as it was sent, on one line.
Hex view
HEX (pre-deserialization) shows the raw bytes Kafka stored, not the deserialized text, which is what you need to find out why a message won't decode. Here is the same Avro message as above:
- Display as set to HEX (pre-deserialization).
Each line shows the position of its first byte (in hex), 16 bytes, and the same bytes as text, with a dot for
anything unprintable. Schema Registry messages start with a zero byte and the four-byte schema ID: here
00, then 00 00 00 01 for schema ID 1. A message that starts like that but shows as
hex is most likely being read with the wrong deserializer: switch the search's value deserializer to
Schema Registry (Deserialization &
Formats).
The Headers tab
Headers lists the message's headers by name and value, the value read as text:
Type in Filter headers... to narrow a long list. A message without headers shows No headers.... Right-click a header to copy it, its value, or all headers as a summary.
The Raw tab
Raw puts everything about the message in one text: its partition, offset, timestamp type and time (in UTC), the key and value schema types and IDs, the key and value sizes in bytes, the headers, and the key and value as hex dumps of their bytes before deserialization.
The timestamp type is CREATE_TIME (set by the producer) or LOG_APPEND_TIME (set by the
broker). Raw is the place to check what a producer really sent, independently of the deserializer and display
format chosen; it has its own search box.
Searching within a message
The search box in the Key, Message and Raw tabs (Search key..., Search event/message..., Search for text...) finds text in what the tab shows and selects the first match, scrolling to it; the count beside it reads, for example, 1 of 2 found. Press Enter or the down arrow for the next match and the up arrow for the previous one; both wrap around.
- Plain text ignores case:
customerfindsCustomertoo. - The regex button at the end of the box switches to a Java regular expression, which is case-sensitive
(start it with
(?i)to ignore case). An invalid one shows Invalid regex. - The search searches the formatted text, so for pretty-printed JSON search for
"status" : "NEW", not"status":"NEW", or use a regex such as"status"\s*:\s*"NEW". - The search text stays when you select another message, and is applied to it, so you can step through the results and see where each one matches.
A search with a text filter fills these boxes for you: the filter text goes into the Key box if the filter looks in the key, and the Message box if it looks in the value, with the regex setting carried over, so each match is highlighted when you select a message.
Opening a message in its own window
The eye button (View in Window) in the Key or Message tab opens that key or value in a separate window titled Topic: topic name, in the format chosen in Display as:
- A search box, as in the detail pane.
- Always on top: on by default (orange), so the window stays in front of KafkIO's main window; click it to let the window go behind.
The window holds that one message: it doesn't change when you select another row, and you can open as many as you like, which makes it easy to compare two versions of a record side by side, or keep a message in view while you produce a corrected one. Resize the window to read a large message; Close closes it.
Undocking the detail pane
To have the whole detail pane in a window instead, for example on a second screen, click Undock window, the arrow at the top right of the pane. The pane, with all four tabs, moves to a window titled Topic: topic name, and the table takes the full height of the tab. Unlike a View in Window window, it follows the selection: select a row in the table and the window shows that message. Click Re-dock window in the window to put the pane back.
Copying messages
Right-click a row in the table:
- Re-produce Message: open the Produce dialog filled in with this message's key, value, headers and serializers, to send it again or a changed copy (Producing Messages).
- Copy Event Summary: this message as text.
- Copy All Event Summaries (N): every message in the table,
separated by lines of
---. - Copy 'text': just the cell you right-clicked (here the key).
An event summary has the same layout as the Raw tab, but with the deserialized key and value as text instead of hex, which is handy to paste into a ticket or a chat:
Partition: 2
Offset: 26
Timestamp: CREATE_TIME 2026-10-25T07:43:46.102Z
Key schema type: none
Key schema ID: none
Value schema type: none
Value schema ID: none
Key size: 11
Value size: 80
Headers:
format = json,
source = kafkio-lab
Key:
customer-12
Value:
{"orderId": 58, "customer": "customer-12", "amount": 444.2, "status": "SHIPPED"}
The value is copied as it was received, not pretty-printed. Copy All Event Summaries copies what's in the table (up to the page size), which suits a few hundred messages; to export a whole topic or many thousands of messages, dump it to a file instead, choosing the fields you want.