Troubleshooting
Messages are quoted as they appear. Search this page for the text of the exception you received.
Startup and configuration
InaccessibleObjectException, or an Arrow memory error on the first batch
Arrow 19 needs --add-opens=java.base/java.nio=ALL-UNNAMED. Add it to the JVM that runs
columnar code, including applications, tests, and any tooling. See
Configuration.
The client never reaches RUNNING, or the group coordinator rejects the protocol
The broker does not support the streams group protocol, or streams.version=1 is not
finalized. Check broker requirements. To run
against an older broker, set group.protocol=classic explicitly, since withDefaults
keeps your value.
No standby task ever appears
Under the streams protocol the broker decides the standby count. On Apache Kafka 4.3.1
set group.streams.num.standby.replicas=1 on the broker;
StreamsConfig.NUM_STANDBY_REPLICAS_CONFIG alone is not enough.
integrationTest reports zero tests
Both integration tests are gated on environment variables. Set
KRABKA_INTEGRATION_BOOTSTRAP or KRABKA_INTEGRATION_SCHEMA_REGISTRY. The task
declares both as inputs, so a changed value forces a re-run.
Schema registry
schema ID for orders-value is not resolved; call registerSubject and prewarm first
The serializer found no ID for the subject. Causes, in order of likelihood:
registerSubject(topic)was never called for this serde.prewarm()was called but not awaited. It returns a future.prewarm()failed; the future completed exceptionally and nothing checked it.- The topic at run time differs from the one passed to
registerSubject, so the computed subject differs. - The source or sink topic passed through
RowCodecdiffers from the topic registered during prewarm.
serde.registerSubject("orders");
cache.prewarm().join(); // await it
assert cache.idForSubject("orders-value").isPresent(); // verify it
SchemaFetchPendingException: writer schema for id 7 is pending fetch
Expected on the first record carrying an unseen schema ID. The fetch is already running;
retry the record. The exception extends Kafka’s RetriableException, so a Streams
deserialization exception handler or a plain consumer retry handles it.
It becomes a problem only if it repeats indefinitely, which means the fetch keeps
failing. Check registry reachability, and whether ID 7 exists at all
(GET /schemas/ids/7).
schema registry returned HTTP 404: {"error_code":40403,...}
Under LOOKUP_ONLY, the exact schema is not registered under that subject. Register it
first, or switch to AUTO_REGISTER in development. Remember that Avro subjects hold the
canonical parsing form, so a schema differing only in documentation or field order
still matches, while any structural difference does not.
40401 means the subject itself does not exist.
schema registry returned HTTP 409
The registry rejected the schema as incompatible with the subject’s existing versions.
Fix the schema or set the subject’s compatibility level with
client.setCompatibility(subject, level).
schema registry request failed, statusCode() == -1
A transport failure: unreachable host, TLS failure, or timeout. The cause carries the
underlying IOException. Configure timeouts and TLS on the HttpClient passed to the
three-argument constructor.
Context paths in the base URI are preserved.
serde role does not match the Kafka key setting
A value serde was configured as default.key.serde, or the reverse. Use
AvroSerde.forKey / forValue (and the equivalents) to match the position. This check
only fires when Kafka configures the serde from configuration.
Protobuf messageType mismatch: writer demo.Other, local demo.Order
The record was written by a different message type than the one this serde reads. Either
the topic carries mixed types, or the subject resolved to the wrong schema ID. Under
USE_LATEST the registry’s messageType is adopted, which makes the mismatch visible
at the first record.
JSON Schema validation failed: ...
The record body does not satisfy its schema. Validation applies on serialization
against the local schema and on deserialization against the writer schema. Set
validate = false to accept it, or fix the producer.
cannot serialize schema value / cannot deserialize schema value
A wrapper around a format-library failure. The cause has the real message: an Avro resolution error, a Protobuf parse failure, or a Jackson binding error.
Wire format
schema frame is shorter than 5 bytes
The record value is not Confluent-framed. Common causes: a topic written by a plain serializer, a compacted tombstone handled as bytes, or a key deserialized with a value serde.
invalid schema frame magic byte 0x01
Same class of problem. The first byte must be 0x00, so some other framing is in use.
truncated Protobuf message-index varint
A Protobuf frame was decoded from bytes that are not one, or the value was truncated in
transit. Confirm the topic really carries Protobuf and that ProtobufSerde (not
AvroSerde) is reading it.
Columnar
A payload column starts with __payload_
The original name collided with a metadata column. Use
BlobCodec.payloadColumn(originalName) while processing it. Sinks restore the original
name automatically.
Arrow batch schemas differ
BlobCodec.decode received records whose Arrow payloads have different schemas. All
records in one fetched batch must share a schema. Reuse one JsonRowBridge, or pass an
explicit Arrow Schema, to keep row batches stable.
decode called with an empty record batch
A codec was called with an empty list. ColumnarRunner guards against this; if you drive
runBatch yourself, skip empty polls.
cannot decode Arrow record 3
The record at index 3 in the fetched batch is not a valid Arrow IPC stream. The cause holds the underlying failure. Check whether that topic mixes Arrow and non-Arrow values.
Arrow column does not exist: sku
select, groupBy, or an aggregation named a column that is not in the batch. Remember
that groupBy drops metadata columns and replaces payload columns with the key and
aggregate columns, so a downstream operator may be looking at a narrower schema than you
expect.
no Arrow union member accepts ...
A withColumns or groupBy value matches none of the declared union children. Return
a value compatible with one child or widen the union field.
groupBy requires at least one key column
An empty key collection was passed. Whole-batch aggregation without a key is not
supported; group by a constant column added with withColumns if you need it.
duplicate node name `same`
Two nodes share a name. Names must be unique across sources, operators, and sinks.
node `sink` has an invalid parent
The parent was added after the child, or the node has no parent. Add nodes in dependency order.
topology has no source / topology has no sink
build() requires at least one of each.
parent is not a node in this topology
A ColumnarNode from a different ColumnarTopology was used as a parent. Nodes are not
portable between topologies.
The allocator throws on close
Arrow reports outstanding allocations, which means a batch was not closed. Work through
the ownership rules: a batch you created and
did not forward is yours to close, and anything returned by decode,
rowsToBatch, or an ArrowIpcSerde deserializer is yours as well. The exception names
the leaked allocations.
runBatch returns an empty list
Either the topic you passed matches no source, or the record list was empty. Both are
silent by design. Check topology.sourceTopics().
Output records have timestamp 0 or a null key
groupBy drops the metadata columns, so a downstream sink has no __timestamp or
__key to read. Group by those columns, or add them back with withColumns. BlobCodec
always produces a null key by design, because it emits batches rather than keyed rows.
The broker rejects a produced record as too large
BlobCodec enforces a 900 KiB hard cap by default and rejects a single row that cannot
fit. Raise both maxRecordBytes and the broker’s max.message.bytes, or reduce row
size.
Offsets never advance
Check that the poll returned records and that commitSync succeeded. Group runners
commit every processed partition after producer flush; transactional runners commit
offsets through the producer transaction.
Build
-Werror fails on a warning
Compilation uses -Xlint:all -Werror. Fix the warning, or scope a @SuppressWarnings
to the smallest possible element, which is what ColumnarRunnerTest does for Kafka’s
deprecated MockConsumer constructor.
Javadoc fails
Javadoc runs with Xdoclint:all and -Werror. A new public type or member must
carry a complete comment — including @param and @return tags — and malformed
HTML, bad @link targets, and broken tags fail the build.
A release job fails on missing credentials
The release workflow asserts MAVEN_CENTRAL_USERNAME, MAVEN_CENTRAL_PASSWORD,
SIGNING_KEY, and SIGNING_PASSWORD before building. Signing is skipped entirely when
SIGNING_KEY is blank, which is why local builds do not need a key. See
Build and release.