apache/beam · error · IOException

Error connecting to JMS

Error message

Error connecting to JMS

What it means

UnboundedJmsReader.start() wraps all connection/session/autoscaler setup in a try block; any Exception from creating the JMS Connection or starting the autoScaler is rethrown as an IOException with the message "Error connecting to JMS". The original exception is chained as the cause, so inspecting it reveals the real problem (bad broker URL, auth failure, network unreachable, etc.).

Solutions

  1. Read the chained cause exception to identify the root failure (ConnectionRefused, JMSSecurityException, etc.).
  2. Verify withUsername/withPassword credentials and the broker URL on each runner worker.
  3. Confirm network connectivity from worker machines to the broker (telnet/host check, firewall rules).
  4. For TLS, validate keystore/truststore configuration on the workers.

Example fix

// before
JmsIO.<JmsRecord>read().withConnectionFactory(cf).withQueue("queue").withUsername("user").withPassword("wrong")
// after
JmsIO.<JmsRecord>read().withConnectionFactory(cf).withQueue("queue")
  .withUsername("user").withPassword(System.getenv("JMS_PASSWORD"))
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight connectivity check
try (Socket s = new Socket()) {
  s.connect(new InetSocketAddress(brokerHost, brokerPort), 5000);
} catch (IOException e) {
  throw new IllegalStateException("broker unreachable before pipeline start", e);
}

Try / catch

try { reader.start(); } catch (IOException e) {
  Throwable root = e; while (root.getCause() != null) root = root.getCause();
  log.error("JMS connect failed: {}", root.toString()); // then retry with backoff
}

Prevention

When it happens

Trigger: Calling start() on the JMS unbounded source when connectionFactory.createConnection() or connection.start() fails: wrong broker URL, broker down, credentials rejected, SSL handshake failure, or autoScaler.start() throwing.

Common situations: Broker unreachable from the runner workers (firewall/VPC), expired username/password, TLS truststore misconfiguration, DNS resolution failure.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/678b0c240ee08728. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/jms/src/main/java/org/apache/beam/sdk/io/jms/JmsIO.java:783

      Read<T> spec = source.spec;
      ConnectionFactory connectionFactory = spec.getConnectionFactory();
      try {
        Connection connection;
        if (spec.getUsername() != null) {
          connection = connectionFactory.createConnection(spec.getUsername(), spec.getPassword());
        } else {
          connection = connectionFactory.createConnection();
        }
        connection.start();
        this.connection = connection;
        if (spec.getAutoScaler() == null) {
          this.autoScaler = new DefaultAutoscaler();
        } else {
          this.autoScaler = spec.getAutoScaler();
        }
        this.autoScaler.start();
      } catch (Exception e) {
        throw new IOException("Error connecting to JMS", e);
      }

      recreateSession();

      return advance();
    }

    @Override
    public boolean advance() throws IOException {
      try {
        Message message;
        synchronized (this) {
          if (receiveTimeoutMillis == 0L) {
            message = this.consumer.receiveNoWait();
          } else {
            message = this.consumer.receive(receiveTimeoutMillis);
          }
          // put add in synchronized to make sure all messages in preparer are in same session

View on GitHub (pinned to 12126d8942)