{"record":{"id":"52b7c7d5dbc28b36","repo":"pentaho/pentaho-kettle","slug":"a-server-socket-allocation-always-has-to-accompanied-by-a","errorCode":null,"errorMessage":"A server socket allocation always has to accompanied by a cluster run ID but it was empty","messagePattern":"A server socket allocation always has to accompanied by a cluster run ID but it was empty","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/www/TransformationMap.java","lineNumber":160,"sourceCode":"   * @param portRangeStart\n   *          the start of the port range as described in the used cluster schema\n   * @param hostname\n   *          the host name to allocate this address for\n   * @param clusteredRunId\n   *          A unique id, created for each new clustered run during transformation split.\n   * @param transformationName\n   * @param sourceStepName\n   * @param sourceStepCopy\n   * @return\n   */\n  public SocketPortAllocation allocateServerSocketPort( int portRangeStart, String hostname,\n    String clusteredRunId, String transformationName, String sourceSlaveName, String sourceStepName,\n    String sourceStepCopy, String targetSlaveName, String targetStepName, String targetStepCopy ) {\n\n    // Do some validations first...\n    //\n    if ( Utils.isEmpty( clusteredRunId ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a cluster run ID but it was empty\" );\n    }\n    if ( portRangeStart <= 0 ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by port range start > 0 but it was \"\n          + portRangeStart );\n    }\n    if ( Utils.isEmpty( hostname ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a hostname but it was empty\" );\n    }\n    if ( Utils.isEmpty( transformationName ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a transformation name but it was empty\" );\n    }\n    if ( Utils.isEmpty( sourceSlaveName ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a source slave server name but it was empty\" );","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/www/TransformationMap.java#L142-L178","documentation":"TransformationMap.allocateServerSocketPort validates its inputs first and throws RuntimeException when clusteredRunId is empty, because every clustered server-socket allocation must be tagged with the cluster run ID used to route data between slave servers. It is a programming/configuration contract violation, not a runtime network failure.","triggerScenarios":"testServerSocketPort or the clustered-transformation setup path invoking allocateServerSocketPort with an empty clusteredRunId — e.g. a TransHopMeta/cluster schema assembled programmatically without generating the run ID, or a caller constructing the clustered plan manually.","commonSituations":"Custom code or plugins building cluster-slice transformations without setting the clustered run ID; older/patched clients calling the Carte API with incomplete parameters; refactored code dropping the runId argument.","solutions":["Ensure the caller generates/propagates a non-empty clusteredRunId (typically a GUID created when the clustered run is planned) before allocating ports.","If calling programmatically, pass the run ID from TransExecutionConfiguration / cluster run context instead of an empty string.","Check for version mismatches between Pentaho/Kettle clients and the Carte server that omit the run ID field.","Fix upstream code that resets or overwrites the clusteredRunId variable before allocation."],"exampleFix":"// before\ntransMap.allocateServerSocketPort(\"\", transName, srcSlave, srcStep, \"0\", tgtSlave, tgtStep, \"0\");\n\n// after\nString clusteredRunId = UUID.randomUUID().toString();\ntransMap.allocateServerSocketPort(clusteredRunId, transName, srcSlave, srcStep, \"0\", tgtSlave, tgtStep, \"0\");","handlingStrategy":"validation","validationCode":"if (clusteredRunId == null || clusteredRunId.isEmpty())\n  throw new IllegalStateException(\"generate a cluster run ID before allocating server sockets\");","typeGuard":null,"tryCatchPattern":"try {\n  transMap.allocateServerSocketPort(clusteredRunId, ...);\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"cluster run ID\")) {\n    throw new ConfigurationException(\"clustered run was planned without a run ID; check cluster setup code\", e);\n  }\n  throw e;\n}","preventionTips":["Always plan clustered executions through the standard TransExecutionConfiguration path, which generates run IDs.","Never pass empty strings for run identifiers in cluster port allocation calls.","Keep Kettle client and Carte server versions aligned."],"tags":["clustering","validation","carte","port","internal"],"backgroundTag":"missing-required-argument","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}