{"record":{"id":"1c07de1a33b1ad4d","repo":"grpc/grpc-java","slug":"scheme-must-start-with-an-alphabetic-char","errorCode":null,"errorMessage":"Scheme must start with an alphabetic char","messagePattern":"Scheme must start with an alphabetic char","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/io/grpc/Uri.java","lineNumber":705,"sourceCode":"    }\n\n    /**\n     * Sets the scheme, e.g. \"https\", \"dns\" or \"xds\".\n     *\n     * <p>This field is required.\n     *\n     * @return this, for fluent building\n     * @throws IllegalArgumentException if the scheme is invalid.\n     */\n    @CanIgnoreReturnValue\n    public Builder setScheme(String scheme) {\n      return setRawScheme(scheme.toLowerCase(Locale.ROOT));\n    }\n\n    @CanIgnoreReturnValue\n    Builder setRawScheme(String scheme) {\n      if (scheme.isEmpty() || !alphaChars.get(scheme.charAt(0))) {\n        throw new IllegalArgumentException(\"Scheme must start with an alphabetic char\");\n      }\n      for (int i = 0; i < scheme.length(); i++) {\n        char c = scheme.charAt(i);\n        if (!schemeChars.get(c)) {\n          throw new IllegalArgumentException(\"Invalid character in scheme at index \" + i);\n        }\n      }\n      this.scheme = scheme;\n      return this;\n    }\n\n    /**\n     * Specifies the new URI's path component as a string of zero or more '/' delimited segments.\n     *\n     * <p>Path segments can consist of any string of codepoints. Codepoints that can't be encoded\n     * literally will be percent-encoded for you.\n     *\n     * <p>If a URI contains an authority component, then the path component must either be empty or","sourceCodeStart":687,"sourceCodeEnd":723,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/api/src/main/java/io/grpc/Uri.java#L687-L723","documentation":"Uri.Builder.setRawScheme() validates the scheme: it must be non-empty, start with an alphabetic character (RFC 3986: ALPHA *( ALPHA / DIGIT / '+' / '-' / '.' )), and contain only scheme-legal characters. An empty or non-alphabetic-initial scheme triggers IllegalArgumentException \"Scheme must start with an alphabetic char\"; a later invalid character produces the index-specific message.","triggerScenarios":"Calling setScheme/setRawScheme with an empty string, a scheme starting with a digit or '-'/'.' (e.g. '3dns', '-grpc'), or a scheme containing ':', '/', or other illegal characters; programmatically splitting \"scheme:rest\" at the wrong index so the scheme string is malformed.","commonSituations":"Manual URI splitting where the colon position is mis-computed (scheme includes preceding chars or is empty); config that stores the scheme separately with numeric values; normalizing schemes from user input without validation.","solutions":["Ensure the scheme starts with a letter and contains only [A-Za-z0-9+.-]","Trim the input and re-split at the first ':' so the scheme excludes stray characters","Prefer Uri.parse()/create() over manually calling setRawScheme with split components","Reject empty schemes at config-load time with a friendly error"],"exampleFix":"// before\nString s = \"1grpc://host\";\nbuilder.setRawScheme(s.substring(0, s.indexOf(':'))); // \"1grpc\" -> throws\n// after\nint i = s.indexOf(\"://\");\nString scheme = s.substring(0, i);\nif (scheme.isEmpty() || !Character.isLetter(scheme.charAt(0))) {\n  throw new IllegalArgumentException(\"Invalid scheme: \" + scheme);\n}\nbuilder.setRawScheme(scheme.toLowerCase(Locale.ROOT));","handlingStrategy":"validation","validationCode":"static boolean validScheme(String s) {\n  if (s == null || s.isEmpty() || !Character.isLetter(s.charAt(0))) return false;\n  return s.chars().allMatch(c -> Character.isLetterOrDigit(c) || c=='+' || c=='-' || c=='.');\n}","typeGuard":"static String normalizeScheme(String s) {\n  return validScheme(s) ? s.toLowerCase(Locale.ROOT) : null;\n}","tryCatchPattern":"try {\n  builder.setRawScheme(scheme);\n} catch (IllegalArgumentException e) {\n  throw new IllegalArgumentException(\"Invalid scheme '\" + scheme + \"': \" + e.getMessage(), e);\n}","preventionTips":["Validate schemes against [A-Za-z][A-Za-z0-9+.-]* before setRawScheme","Split scheme at the first ':' only, and trim whitespace","Lowercase schemes after validation"],"tags":["uri","scheme","rfc3986","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"}