{"record":{"id":"ca580ea991c8ee0c","repo":"grpc/grpc-java","slug":"at-least-one-credential-is-required-ca580e","errorCode":null,"errorMessage":"At least one credential is required","messagePattern":"At least one credential is required","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/io/grpc/ChoiceServerCredentials.java","lineNumber":36,"sourceCode":"\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Provides a list of {@link ServerCredentials}, where any one may be used. The credentials are in\n * preference order.\n */\npublic final class ChoiceServerCredentials extends ServerCredentials {\n  /**\n   * Constructs with the provided {@code creds} as options, with preferred credentials first.\n   *\n   * @throws IllegalArgumentException if no creds are provided\n   */\n  public static ServerCredentials create(ServerCredentials... creds) {\n    if (creds.length == 0) {\n      throw new IllegalArgumentException(\"At least one credential is required\");\n    }\n    return new ChoiceServerCredentials(creds);\n  }\n\n  private final List<ServerCredentials> creds;\n\n  private ChoiceServerCredentials(ServerCredentials... creds) {\n    for (ServerCredentials cred : creds) {\n      if (cred == null) {\n        throw new NullPointerException();\n      }\n    }\n    this.creds = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(creds)));\n  }\n\n  /** Non-empty list of credentials, in preference order. */\n  public List<ServerCredentials> getCredentialsList() {\n    return creds;","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/api/src/main/java/io/grpc/ChoiceServerCredentials.java#L18-L54","documentation":"ChoiceServerCredentials.create() builds a server credentials object that tries its options in preference order. It requires at least one ServerCredentials; calling create() with an empty varargs array throws IllegalArgumentException.","triggerScenarios":"Calling ServerCredentials.create() / ChoiceServerCredentials.create() with zero arguments, typically by spreading an empty collection of server credentials (e.g..toArray(new ServerCredentials[0])) or by omitting arguments.","commonSituations":"Building server credentials from config where TLS cert/key entries are missing; feature flags disabling all credential sources; migration code that used to pass TlsServerCredentials plus a fallback but the fallback was removed.","solutions":["Always pass at least one ServerCredentials, e.g. TlsServerCredentials.create() or InsecureServerCredentials.create() as a fallback","Validate the credentials list is non-empty before calling create() and fail with a descriptive configuration error","Check the server configuration/cert paths so at least one credential can be constructed"],"exampleFix":"// before\nServerCredentials creds = ChoiceServerCredentials.create(serverCredsList.toArray(new ServerCredentials[0]));\n// after\nif (serverCredsList.isEmpty()) {\n  serverCredsList.add(InsecureServerCredentials.create()); // or throw a clear config error\n}\nServerCredentials creds = ChoiceServerCredentials.create(serverCredsList.toArray(new ServerCredentials[0]));","handlingStrategy":"validation","validationCode":"if (serverCredsList == null || serverCredsList.isEmpty()) {\n  throw new IllegalArgumentException(\"At least one ServerCredentials must be configured\");\n}\nServerCredentials creds = ChoiceServerCredentials.create(serverCredsList.toArray(new ServerCredentials[0]));","typeGuard":null,"tryCatchPattern":"try {\n  ServerCredentials creds = ChoiceServerCredentials.create(credArray);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"At least one credential is required\")) {\n    creds = InsecureServerCredentials.create(); // or surface a config error\n  } else throw e;\n}","preventionTips":["Keep a default server credential (TLS or insecure) in every deployment configuration","Validate cert/key configuration at startup so credential construction cannot yield an empty list","Reject empty credentials sections in config parsing with a clear error message"],"tags":["illegal-argument","credentials","validation","server"],"backgroundTag":"missing-required-argument","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"}