apache/beam · error · IllegalArgumentException
Unknown JMS provider
Error message
Unknown JMS provider '%s' for INDIVIDUAL_ACKNOWLEDGE. Please specify the code explicitly via Read#withIndividualAcknowledgeModeCode(int).
What it means
When reading JMS messages with the INDIVIDUAL_ACKNOWLEDGE mode, Beam's JmsIO must map the underlying JMS connection factory class to a provider-specific acknowledge mode code (e.g. ActiveMQ=4, Qpid/Artemis=101). If the connection class name is not one of the recognized providers, UnboundedJmsReader throws this IllegalArgumentException. The workaround is to set the provider-specific code yourself via Read#withIndividualAcknowledgeModeCode(int).
Solutions
- Call JmsIO.read().withIndividualAcknowledgeModeCode(<code>) with your provider's documented individual-acknowledge mode code.
- If using a wrapped/pooled ConnectionFactory, ensure the underlying class name contains the broker package, or set the explicit code regardless.
- Check the broker's JMSSessionMode documentation (e.g. ActiveMQ Session.INDIVIDUAL_ACKNOWLEDGE=4) and pass that value.
Example fix
// before JmsIO.<JmsRecord>read().withConnectionFactory(cf).withAcknowledgeMode(JmsIO.INDIVIDUAL_ACKNOWLEDGE) // after (e.g. IBM MQ code 4 / provider-specific) JmsIO.<JmsRecord>read().withConnectionFactory(cf) .withAcknowledgeMode(JmsIO.INDIVIDUAL_ACKNOWLEDGE) .withIndividualAcknowledgeModeCode(4)
Defensive patterns
Strategy: validation
Validate before calling
String cls = connectionFactory.getClass().getName();
boolean known = cls.contains("org.apache.activemq") || cls.contains("org.apache.qpid.jms") || cls.contains("org.apache.activemq.artemis");
if (!known) {
// must call .withIndividualAcknowledgeModeCode(code)
} Prevention
- Always set withIndividualAcknowledgeModeCode explicitly when the broker is not stock ActiveMQ/Qpid/Artemis.
- Log the connection factory class name during pipeline construction to catch wrapper classes.
When it happens
Trigger: Creating a JmsIO.read() source with withAcknowledgeMode(JmsIO.INDIVIDUAL_ACKNOWLEDGE) whose connection factory class name (from withConnectionFactory) is not apache-activemq, qpid-jms, or artemis — e.g. IBM MQ, Solace, or a custom ConnectionFactory — and no explicit individualAcknowledgeModeCode was configured.
Common situations: Migrating a pipeline to a different JMS broker; using a wrapper or pooled ConnectionFactory whose class name doesn't contain the broker package; copying a config from an ActiveMQ project to another broker.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- A 'datagen' table requires either 'rows-per-second' (for…
- A schema was provided without a data format (or viceversa)…
- An error occurred
- Attempting to add message
- Batch size is too large! It should be smaller or equal than
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/94cdb072239f93d9.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/jms/src/main/java/org/apache/beam/sdk/io/jms/JmsIO.java:752
private int getAckModeCode(AcknowledgeMode mode) {
if (mode == AcknowledgeMode.CLIENT_ACKNOWLEDGE
|| mode == AcknowledgeMode.CLIENT_ACKNOWLEDGE_UNSAFE) {
return Session.CLIENT_ACKNOWLEDGE;
} else if (mode == AcknowledgeMode.INDIVIDUAL_ACKNOWLEDGE) {
Integer configuredCode = source.spec.getIndividualAcknowledgeModeCode();
if (configuredCode != null) {
return configuredCode;
}
String connectionClassName = this.connection.getClass().getName();
if (connectionClassName.contains("org.apache.activemq.ActiveMQConnection")) {
return 4;
} else if (connectionClassName.contains("org.apache.qpid.jms")) {
return 101;
} else if (connectionClassName.contains("org.apache.activemq.artemis")) {
return 101;
} else {
throw new IllegalArgumentException(
String.format(
"Unknown JMS provider '%s' for INDIVIDUAL_ACKNOWLEDGE. "
+ "Please specify the code explicitly via Read#withIndividualAcknowledgeModeCode(int).",
connectionClassName));
}
} else {
throw new IllegalArgumentException(String.format("Unknown AcknowledgeMode: %s", mode));
}
}
@Override
public boolean start() throws IOException {
Read<T> spec = source.spec;
ConnectionFactory connectionFactory = spec.getConnectionFactory();
try {
Connection connection;
if (spec.getUsername() != null) {
connection = connectionFactory.createConnection(spec.getUsername(), spec.getPassword());View on GitHub (pinned to 12126d8942)