apache/beam · error · RuntimeException
Invalid JMSMessageID
Error message
Invalid JMSMessageID %s while requiresDeduping is set. Data loss possible.
What it means
When the JmsIO read source is configured with withRequiresDeduping(true), Beam relies on the JMSMessageID as the deduplication key; per the JMS spec message IDs start with "ID:". If the received message's ID is null-truncated to 3 chars or shorter, deduping would silently drop data, so the reader throws a RuntimeException warning that data loss is possible.
Solutions
- Ensure producers generate valid JMSMessageIDs: disable any 'disableMessageID' optimization on MessageProducer/sender config.
- If IDs are legitimately absent, remove withRequiresDeduping(true) from the read spec.
- Verify the broker conforms to the JMS spec regarding ID generation ("ID:" prefix).
Example fix
// before (producer side) producer.setDisableMessageID(true); // after producer.setDisableMessageID(false); // or drop withRequiresDeduping() from the Beam source
Defensive patterns
Strategy: validation
Validate before calling
// before enabling deduping, verify producers set message IDs
String id = message.getJMSMessageID();
boolean safeForDedup = id != null && id.length() > 3 && id.startsWith("ID:");
if (!safeForDedup) { /* don't call withRequiresDeduping(true) */ } Try / catch
try { reader.advance(); } catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("Invalid JMSMessageID")) {
// disable requiresDeduping or fix producer config
}
} Prevention
- Never set producer.setDisableMessageID(true) when consuming with requiresDeduping.
- Test with production broker settings that may strip or shorten message IDs.
When it happens
Trigger: Receiving a JMS message whose getJMSMessageID() returns null or a string of length <= 3 (e.g. "" or "ID:") while source.spec.isRequiresDeduping() is true.
Common situations: Producers that override/disable message IDs for performance (e.g. non-persistent messages with optimized ID generation), non-compliant broker implementations, or messages routed through bridges that strip IDs.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- An error occurred
- Attempting to add message
- ConnectionFactory does not exist. If using expansion…
- drop_duplicates(keep= ) is not supported because it is…
- Dropping output field
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/ac4f5370ab5cb2f5.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/jms/src/main/java/org/apache/beam/sdk/io/jms/JmsIO.java:821
checkpointMarkPreparer.add(message);
}
}
if (message == null) {
currentMessage = null;
return false;
}
currentMessage = this.source.spec.getMessageMapper().mapMessage(message);
currentTimestamp = new Instant(message.getJMSTimestamp());
String messageID = message.getJMSMessageID();
if (messageID != null) {
if (this.source.spec.isRequiresDeduping()) {
// per JMS specification, message ID has prefix "id:". The runner use it to dedup
// message. Empty or non-exist message id (possible for optimization configuration set)
// will cause data loss.
if (messageID.length() <= 3) {
throw new RuntimeException(
String.format(
"Invalid JMSMessageID %s while requiresDeduping is set. Data loss possible.",
messageID));
}
}
currentID = messageID.getBytes(StandardCharsets.UTF_8);
} else {
currentID = EMPTY;
}
return true;
} catch (Exception e) {
throw new IOException(e);
}
}
@Override
public T getCurrent() throws NoSuchElementException {View on GitHub (pinned to 12126d8942)