{"record":{"id":"766df5729334121a","repo":"openzipkin/zipkin","slug":"s-has-an-invalid-port","errorCode":null,"errorMessage":"%s has an invalid port","messagePattern":"(.+?) has an invalid port","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"zipkin-storage/cassandra/src/main/java/zipkin2/storage/cassandra/internal/HostAndPort.java","lineNumber":85,"sourceCode":"          host = hostPort.substring(0, colonIndex);\n          endHostIndex = colonIndex;\n        } else if (!Endpoint.newBuilder().parseIp(hostPort)) { // reuse our IPv6 validator\n          throw new IllegalArgumentException(hostPort + \" is an invalid IPv6 literal\");\n        }\n      }\n    }\n    if (host.isEmpty()) throw new IllegalArgumentException(hostPort + \" has an empty host\");\n    if (endHostIndex + 1 < hostPort.length() && hostPort.charAt(endHostIndex) == ':') {\n      return new HostAndPort(host, validatePort(hostPort.substring(endHostIndex + 1), hostPort));\n    }\n    return new HostAndPort(host, defaultPort);\n  }\n\n  static int validatePort(String portString, String hostPort) {\n    for (int i = 0, length = portString.length(); i < length; i++) {\n      char c = portString.charAt(i);\n      if (c >= '0' && c <= '9') continue; // isDigit\n      throw new IllegalArgumentException(hostPort + \" has an invalid port\");\n    }\n    int result = Integer.parseInt(portString);\n    if (result == 0 || result > 0xffff) {\n      throw new IllegalArgumentException(hostPort + \" has an invalid port\");\n    }\n    return result;\n  }\n}\n","sourceCodeStart":67,"sourceCodeEnd":94,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin-storage/cassandra/src/main/java/zipkin2/storage/cassandra/internal/HostAndPort.java#L67-L94","documentation":"validatePort throws IllegalArgumentException('%s has an invalid port') when the port substring contains a non-digit character. The parser scans each char and rejects anything outside '0'-'9' before Integer.parseInt, so values like '90a2' or '9042 ' (whitespace) fail here with the full host:port string in the message.","triggerScenarios":"Passing 'host:9o42', 'host:9042,host2:9042' (un-split list), or a port with trailing whitespace/newline from a config file.","commonSituations":"CRLF line endings in properties files appending \\r to the port; forgetting to split comma-separated CASSANDRA_CONTACT_POINTS before parsing.","solutions":["Fix the port to digits only, e.g. 'host:9042'.","Trim whitespace and split lists on ',' before calling fromString.","Normalize config files (strip CR) or use env vars instead of multi-line properties."],"exampleFix":"// before\nfor (String hp : contactPoints) HostAndPort.fromString(hp, 9042); // one entry: \"host:9042\\r\"\n\n// after\nfor (String hp : contactPoints) HostAndPort.fromString(hp.trim(), 9042);","handlingStrategy":"validation","validationCode":"static boolean hasDigitsOnlyPort(String hostPort) {\n  int c = hostPort.lastIndexOf(':');\n  if (c < 0) return true;\n  String p = hostPort.substring(c + 1);\n  return !p.isEmpty() && p.chars().allMatch(ch -> ch >= '0' && ch <= '9');\n}\nif (!hasDigitsOnlyPort(trimmed)) throw new IllegalArgumentException(\"Port must be digits: \" + hostPort);","typeGuard":null,"tryCatchPattern":"catch (IllegalArgumentException e) { if (e.getMessage().endsWith(\"has an invalid port\")) failConfigValidation(e.getMessage()); else throw e; }","preventionTips":["Trim every contact-point entry before parsing.","Split comma-separated lists before passing individual entries."],"tags":["cassandra","zipkin","port","contact-points","validation"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}