{"record":{"id":"73e06d5041e7a8b3","repo":"grpc/grpc-java","slug":"missing-required-scheme","errorCode":null,"errorMessage":"Missing required scheme.","messagePattern":"Missing required scheme\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/io/grpc/Uri.java","lineNumber":231,"sourceCode":"   */\n  public static Uri create(String s) {\n    Builder builder = new Builder();\n    int i = 0;\n    final int n = s.length();\n\n    // 3.1. Scheme: Look for a ':' before '/', '?', or '#'.\n    int schemeColon = -1;\n    for (; i < n; ++i) {\n      char c = s.charAt(i);\n      if (c == ':') {\n        schemeColon = i;\n        break;\n      } else if (c == '/' || c == '?' || c == '#') {\n        break;\n      }\n    }\n    if (schemeColon < 0) {\n      throw new IllegalArgumentException(\"Missing required scheme.\");\n    }\n    builder.setRawScheme(s.substring(0, schemeColon));\n\n    // 3.2. Authority. Look for '//' then keep scanning until '/', '?', or '#'.\n    i = schemeColon + 1;\n    if (i + 1 < n && s.charAt(i) == '/' && s.charAt(i + 1) == '/') {\n      // \"//\" just means we have an authority. Skip over it.\n      i += 2;\n\n      int authorityStart = i;\n      for (; i < n; ++i) {\n        char c = s.charAt(i);\n        if (c == '/' || c == '?' || c == '#') {\n          break;\n        }\n      }\n      builder.setRawAuthority(s.substring(authorityStart, i));\n    }","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/api/src/main/java/io/grpc/Uri.java#L213-L249","documentation":"Uri.create() implements RFC 3986 parsing and requires every absolute URI to begin with a scheme followed by ':'. If scanning the string finds no ':' before the first '/', '?' or '#' (schemeColon < 0), it throws IllegalArgumentException \"Missing required scheme.\" — unlike java.net.URI, grpc's Uri does not accept scheme-less URI references.","triggerScenarios":"Passing a URI string with no scheme: \"localhost:50051\" without prefix is fine, but \"//host/x\", \"host/path\", or a bare target like \"dns:///...\" is fine too — the failing case is strings like \"example.com/foo\" or \"#frag\" where no colon appears before the first '/', '?', or '#'.","commonSituations":"gRPC target strings like \"localhost:50051\" are OK (scheme='localhost') but strings such as \"my-service.my-ns:50051\" typed without scheme in configs; ODBC-style or browser-style relative URLs reused as gRPC targets; stripping the scheme manually before calling create().","solutions":["Prepend an explicit scheme to the string (e.g. \"https://\" or the appropriate scheme) before parsing","If the string is a host:port, wrap it in the desired scheme form before passing to Uri.create()","Use Uri.parse() and catch the error to give users a clearer validation message","Validate config values at startup to require an absolute URI"],"exampleFix":"// before\nUri.create(\"example.com/api\"); // throws: no scheme\n// after\nUri.create(\"https://example.com/api\");","handlingStrategy":"validation","validationCode":"if (!target.matches(\"[A-Za-z][A-Za-z0-9+.-]*:.*\")) throw new IllegalArgumentException(\"Target requires a scheme: \" + target);","typeGuard":null,"tryCatchPattern":"try {\n  uri = Uri.create(target);\n} catch (IllegalArgumentException e) {\n  throw new InvalidEndpointException(\"Target missing scheme: \" + target, e);\n}","preventionTips":["Require absolute URIs in configuration; reject scheme-less strings at load time","Document expected target formats (e.g. 'dns:///host:port') for users","Provide a default scheme when the input is known to be a bare host/path"],"tags":["uri","rfc3986","missing-scheme","validation"],"backgroundTag":"invalid-url-format","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}