Distributed JMeter runs depend on Java RMI connections between one controller and each remote engine. Pinning the registry, engine, and controller callback ports keeps firewalls, container port mappings, and security groups from having to allow unpredictable ephemeral ports.

The worker side uses two different RMI ports. SERVER_PORT sets the registry port that the controller contacts first, while server.rmi.localport fixes the remote engine object port announced through that registry.

The controller can also open RMI listener ports while remote samples and thread events return from workers. Set client.rmi.localport to a known base port and keep the existing RMI SSL mode consistent on every node before testing the port change.

Steps to set JMeter remote RMI ports:

  1. Choose the fixed RMI ports for the distributed run.
    Worker RMI registry: 1664/tcp
    Worker engine port: 4000/tcp
    Controller callback base: 5000/tcp
    Controller callback range: 5000-5002/tcp

    Current JMeter documentation says client.rmi.localport can open up to three controller-side ports beginning with the configured base.

  2. Allow the port directions in the firewall, security group, or container port map.
    Controller -> worker-01:1664/tcp
    Controller -> worker-01:4000/tcp
    worker-01  -> controller:5000-5002/tcp

    Open the worker registry and engine ports toward each worker. Open the controller callback range toward the controller host only from trusted remote engines.

  3. Start the remote engine with the fixed worker-side ports.
    $ SERVER_PORT=1664 jmeter-server \
      -Jserver.rmi.localport=4000 \
      -Jserver.rmi.ssl.disable=true
    2026-06-30 07:52:11,158 INFO Using local port: 4000
    Created remote object: UnicastServerRef2 [endpoint:[worker-01:4000]]

    Use server.rmi.ssl.disable=true only on an isolated load-test network. Keep RMI SSL enabled and configure the matching keystore on every node when the controller and workers cross an untrusted network.
    Related: How to configure SSL for JMeter remote testing

  4. Run the controller against the worker registry port and fixed controller callback base.
    $ jmeter -n \
      -t remote-smoke.jmx \
      -l remote-rmi-results.jtl \
      -j controller.log \
      -Jclient.rmi.localport=5000 \
      -Jserver.rmi.ssl.disable=true \
      -R worker-01:1664 \
      -X
    Creating summariser <summary>
    Created the tree successfully using remote-smoke.jmx
    Configuring remote engine: worker-01:1664
    Starting distributed test with remote engines: [worker-01:1664]
    Remote engines have been started:[worker-01:1664]
    summary =      1 in 00:00:00 =    2.6/s Avg:   345 Min:   345 Max:   345 Err:     0 (0.00%)
    Tidying up remote
    Exiting remote servers:[worker-01:1664]
    ... end of run

    -R worker-01:1664 supplies the remote engine list for this run. Use remote_hosts=worker-01:1664 in the controller properties file only when the same worker list should be reused by default.
    Related: How to run a distributed JMeter test

  5. Check the result file for samples returned by the remote engine.
    $ cat remote-rmi-results.jtl
    timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect
    1782805932605,345,remote-rmi-port-smoke,200,OK,worker-01:1664-Remote users 1-1,text,true,,20,0,1,1,null,0,0,0

    The threadName value should include the remote host:port entry, and the success column should contain true for the smoke sample.

  6. Review the remote engine log for the fixed registry and engine ports.
    $ cat jmeter-server.log
    2026-06-30 07:52:11,154 INFO o.a.j.JMeter: Setting System property: server_port=1664
    2026-06-30 07:52:11,154 INFO o.a.j.JMeter: Setting JMeter property: server.rmi.localport=4000
    2026-06-30 07:52:11,154 INFO o.a.j.JMeter: Setting JMeter property: server.rmi.ssl.disable=true
    2026-06-30 07:52:11,158 INFO Using local port: 4000
    Created remote object: UnicastServerRef2 [endpoint:[worker-01:4000]]
    2026-06-30 07:52:11,332 INFO o.a.j.e.RemoteJMeterEngineImpl: Bound to RMI registry on port 1664
    ##### snipped #####
    Starting the test on host worker-01:1664
    Finished the test on host worker-01:1664