{"record":{"id":"43127e93f7b866e9","repo":"apache/druid","slug":"path-must-start-with","errorCode":null,"errorMessage":"Path must start with '/'","messagePattern":"Path must start with '/'","errorType":"validation","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/indexer/TaskLocation.java","lineNumber":140,"sourceCode":"      return HostAndPort.fromParts(host, thePort).toString();\n    }\n  }\n\n  public URL makeURL(final String encodedPathAndQueryString) throws MalformedURLException\n  {\n    final String scheme;\n    final int portToUse;\n\n    if (tlsPort > 0) {\n      scheme = \"https\";\n      portToUse = tlsPort;\n    } else {\n      scheme = \"http\";\n      portToUse = port;\n    }\n\n    if (!encodedPathAndQueryString.startsWith(\"/\")) {\n      throw new IAE(\"Path must start with '/'\");\n    }\n\n    // Use URL constructor, not URI, since the path is already encoded.\n    return new URL(scheme, host, portToUse, encodedPathAndQueryString);\n  }\n\n  @Override\n  public String toString()\n  {\n    return \"TaskLocation{\" +\n           \"host='\" + host + '\\'' +\n           \", port=\" + port +\n           \", tlsPort=\" + tlsPort +\n           \", k8sPodName=\" + k8sPodName +\n           '}';\n  }\n\n  @Override","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/indexer/TaskLocation.java#L122-L158","documentation":"TaskLocation.makeURL builds the URL used to fetch task logs, and requires the encoded path-and-query string to begin with '/'. A path missing the leading slash would otherwise produce a malformed relative URL, so an IAE is thrown.","triggerScenarios":"Calling makeTaskLocationURL (or makeURL) with a log file path / pathAndQueryString that does not start with '/', e.g. 'status/123/log' instead of '/status/123/log'.","commonSituations":"Custom task log reporters or manually constructed TaskLocation with a hand-built path; overlord/task-status UI integrations that build log paths from non-standard sources.","solutions":["Ensure the path argument starts with '/' before calling makeURL/makeTaskLocationURL.","Normalize the path with a leading slash programmatically.","Check the source of the path (config or API) for missing slash formatting."],"exampleFix":"// before\nString path = \"status/abc/log\";\n// after\nString path = (p.startsWith(\"/\") ? p : \"/\" + p);","handlingStrategy":"validation","validationCode":"String path = rawPath.startsWith(\"/\") ? rawPath : \"/\" + rawPath;\ntaskLocation.makeTaskLocationURL(host, port, useTls, path);","typeGuard":"boolean isValidLogPath(String p) { return p != null && p.startsWith(\"/\"); }","tryCatchPattern":"try { url = location.makeTaskLocationURL(host, port, tls, path); } catch (IAE e) { if (e.getMessage().contains(\"Path must start\")) { path = \"/\" + path; url = location.makeTaskLocationURL(host, port, tls, path); } }","preventionTips":["Always normalize log paths to begin with '/'","Construct paths via URI builders rather than string concatenation","Validate TaskLocation fields when deserializing from external sources"],"tags":["url","validation","task-logs"],"backgroundTag":"invalid-url-format","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}