apache/pulsar · error · RuntimeException

Invalid message config key '

Error message

Invalid message config key '

What it means

TypedMessageBuilderImpl.loadConf(Map) applies known message config keys via a switch; any key not matching a CONF_* constant hits the default branch and throws RuntimeException("Invalid message config key '" + key + "'"). loadConf only supports a fixed set of message property names, so a typo or an unsupported key is a hard error.

Source

Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/TypedMessageBuilderImpl.java:270

                    this.sequenceId(checkType(value, Long.class));
                    break;
                case CONF_REPLICATION_CLUSTERS:
                    this.replicationClusters(checkType(value, List.class));
                    break;
                case CONF_DISABLE_REPLICATION:
                    boolean disableReplication = checkType(value, Boolean.class);
                    if (disableReplication) {
                        this.disableReplication();
                    }
                    break;
                case CONF_DELIVERY_AFTER_SECONDS:
                    this.deliverAfter(checkType(value, Long.class), TimeUnit.SECONDS);
                    break;
                case CONF_DELIVERY_AT:
                    this.deliverAt(checkType(value, Long.class));
                    break;
                default:
                    throw new RuntimeException("Invalid message config key '" + key + "'");
            }
        });
        return this;
    }

    public MessageMetadata getMetadataBuilder() {
        return msgMetadata;
    }

    public Message<T> getMessage() {
        beforeSend();
        return MessageImpl.create(msgMetadata, content, schema, getTopic());
    }

    public long getPublishTime() {
        return msgMetadata.getPublishTime();
    }

View on GitHub (pinned to 820761864e)

Solutions

  1. Fix the key name to one of the supported TypedMessageBuilder config keys (e.g. 'deliverAt', 'deliverAfter', 'eventTime', 'sequenceId', 'properties').
  2. Replace loadConf with direct builder calls (typedMessageBuilder.deliverAt(...), .properties(...)) so the compiler catches mistakes.
  3. Validate incoming conf map keys against the supported whitelist before calling loadConf.

Example fix

// before
builder.loadConf(Map.of("deliverAtTime", System.currentTimeMillis() + 5000));
// after
builder.loadConf(Map.of("deliverAt", System.currentTimeMillis() + 5000));
Defensive patterns

Strategy: validation

Validate before calling

Set<String> ALLOWED = Set.of("key", "properties", "eventTime", "sequenceId",
    "replicationClusters", "disableReplication", "deliverAt", "deliverAfter", "value");
conf.keySet().forEach(k -> {
    if (!ALLOWED.contains(k)) throw new IllegalArgumentException("Unsupported message config key: " + k);
});

Try / catch

try {
    builder.loadConf(conf);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("Invalid message config key")) {
        log.error("bad message conf key: {}", e.getMessage());
    } else throw e;
}

Prevention

When it happens

Trigger: Passing a Map to TypedMessageBuilder.loadConf() containing any key not in the supported set (key, properties, eventTime, sequenceId, replicationClusters, disableReplication, deliverAt, deliverAfter, value, etc.), e.g. a misspelled 'deliverAtTime' instead of 'deliverAt'.

Common situations: Reusing producer-level config keys in message conf; typos after refactoring from deprecated keys; building conf maps from external config files where keys are not validated; copy-pasting keys between loadConf on Producer and on TypedMessageBuilder which accept different key sets.

Related errors


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