{"record":{"id":"25a8128a48a14a1d","repo":"pentaho/pentaho-kettle","slug":"a-server-socket-allocation-always-has-to-accompanied-by-a-25a812","errorCode":null,"errorMessage":"A server socket allocation always has to accompanied by a source step copy but it was empty","messagePattern":"A server socket allocation always has to accompanied by a source step copy but it was empty","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/www/TransformationMap.java","lineNumber":193,"sourceCode":"    }\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\" );\n    }\n    if ( Utils.isEmpty( targetSlaveName ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a target slave server name but it was empty\" );\n    }\n    if ( Utils.isEmpty( sourceStepName ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a source step name but it was empty\" );\n    }\n    if ( Utils.isEmpty( targetStepName ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a target step name but it was empty\" );\n    }\n    if ( Utils.isEmpty( sourceStepCopy ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a source step copy but it was empty\" );\n    }\n    if ( Utils.isEmpty( targetStepCopy ) ) {\n      throw new RuntimeException(\n        \"A server socket allocation always has to accompanied by a target step copy but it was empty\" );\n    }\n\n      // Look up the sockets list for the given host\n      //\n    List<SocketPortAllocation> serverSocketPorts;\n    serverSocketPorts = hostServerSocketPortsMap.computeIfAbsent( hostname, k -> new CopyOnWriteArrayList<>() );\n    serverSocketPorts = serverSocketPorts != null ? serverSocketPorts : hostServerSocketPortsMap.get( hostname );\n\n        // Find the socket port allocation in the list...\n        //\n    SocketPortAllocation socketPortAllocation = null;\n    int maxPort = portRangeStart - 1;\n    for ( int index = 0; index < serverSocketPorts.size(); index++ ) {","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/www/TransformationMap.java#L175-L211","documentation":"Thrown by TransformationMap.allocateServerSocketPort when sourceStepCopy is empty. In clustered transformations a step can run in multiple copies; the copy number ('0', '1', ...) disambiguates which copy owns the socket. Empty copy strings would make the allocation ambiguous, so it is rejected.","triggerScenarios":"Calling allocateServerSocketPort with sourceStepCopy=null or \"\"; partitioned/serviced cluster steps whose copy numbering was not generated.","commonSituations":"Partitioning schema applied without generating copies; programmatic cluster registration hardcoding copies incorrectly; legacy transformations predating copy-aware clustering.","solutions":["Generate proper partition/copy numbering (e.g. \"0\") for the clustered source step before registration","Pass the source step's copy string to allocateServerSocketPort","Validate with Utils.isEmpty( sourceStepCopy ) before the call"],"exampleFix":"// before\nmap.allocateServerSocketPort( 40000, host, trans, src, tgt, \"stepA\", \"stepB\", \"\", \"0\" );\n// after\nmap.allocateServerSocketPort( 40000, host, trans, src, tgt, \"stepA\", \"stepB\", sourceCopyNr, \"0\" );","handlingStrategy":"validation","validationCode":"if ( Utils.isEmpty( sourceStepCopy ) ) {\n  throw new IllegalArgumentException( \"source step copy number required\" );\n}","typeGuard":"boolean hasCopy(String s) { return s != null && s.matches( \"\\\\d+\" ); }","tryCatchPattern":"try {\n  map.allocateServerSocketPort( port, host, trans, src, tgt, stepA, stepB, srcCopy, tgtCopy );\n} catch ( RuntimeException e ) {\n  if ( e.getMessage().contains( \"source step copy\" ) ) {\n    // regenerate partition/copy numbering\n  }\n}","preventionTips":["Always generate copy numbers when using partitioned cluster steps","Pass explicit copy strings ('0' default) in programmatic registrations","Keep partitioning schemas consistent across masters and slaves"],"tags":["java","kettle","carte","clustering"],"backgroundTag":"empty-required-field","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"}