{"record":{"id":"92d1d1ad097c9993","repo":"grpc/grpc-java","slug":"invalid-san-entry","errorCode":null,"errorMessage":"Invalid SAN entry","messagePattern":"Invalid SAN entry","errorType":"validation","errorClass":"CertificateParsingException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/internal/security/trust/XdsX509TrustManager.java","lineNumber":180,"sourceCode":"        ? sanToVerifyExact.equalsIgnoreCase(altNameFromCert)\n        : sanToVerifyExact.equals(altNameFromCert);\n  }\n\n  private static boolean verifyDnsNameInSanList(\n      String altNameFromCert, List<StringMatcher> verifySanList) {\n    for (StringMatcher verifySan : verifySanList) {\n      if (verifyDnsNameInPattern(altNameFromCert, verifySan)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  private static boolean verifyOneSanInList(List<?> entry, List<StringMatcher> verifySanList)\n      throws CertificateParsingException {\n    // from OkHostnameVerifier.getSubjectAltNames\n    if (entry == null || entry.size() < 2) {\n      throw new CertificateParsingException(\"Invalid SAN entry\");\n    }\n    Integer altNameType = (Integer) entry.get(0);\n    if (altNameType == null) {\n      throw new CertificateParsingException(\"Invalid SAN entry: null altNameType\");\n    }\n    switch (altNameType) {\n      case ALT_DNS_NAME:\n      case ALT_URI_NAME:\n      case ALT_IPA_NAME:\n        return verifyDnsNameInSanList((String) entry.get(1), verifySanList);\n      default:\n        return false;\n    }\n  }\n\n  // logic from Envoy::Extensions::TransportSockets::Tls::ContextImpl::verifySubjectAltName\n  private static void verifySubjectAltNameInLeaf(\n      X509Certificate cert, List<StringMatcher> verifyList) throws CertificateException {","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/internal/security/trust/XdsX509TrustManager.java#L162-L198","documentation":"verifyOneSanInList inspects one entry of a certificate's subjectAltName list, expecting a [type, value] pair with at least two elements. Entries that are null or shorter than 2 elements cannot be interpreted, so it throws CertificateParsingException('Invalid SAN entry'). This guards against malformed SAN data returned from certificate parsing.","triggerScenarios":"During SAN verification (verifySubjectAltNameInLeaf), iterating cert.getSubjectAlternativeNames() (or an equivalent list) and encountering a malformed entry: null entry or a list with fewer than 2 elements (e.g. a bare type without value); thrown before the altNameType switch.","commonSituations":"Certificates with unusual/legacy SAN encodings that some BouncyCastle/conscrypt parsers decode into short lists; hand-built test certificates; third-party security providers producing non-standard collection shapes.","solutions":["Regenerate or replace the certificate so it contains well-formed SAN extensions (type+value pairs)","Try a different security provider (e.g. switch JCE/conscrypt version) if the parser is producing malformed SAN lists","Catch CertificateParsingException in the handshake path and fail verification cleanly with a diagnostic of the offending certificate","Inspect the peer certificate with openssl x509 -text to confirm SAN structure before assuming a library bug"],"exampleFix":"// before: cert with malformed SAN extension (single-element entry)\n// regenerate:\n// after\nopenssl x509 -req -extfile <(printf \"subjectAltName=DNS:foo.example.com\") ...","handlingStrategy":"validation","validationCode":"// Filter malformed SAN entries before verification\nboolean wellFormedSan(List<?> entry) {\n  return entry != null && entry.size() >= 2 && entry.get(0) instanceof Integer;\n}","typeGuard":"static boolean isSanEntry(List<?> entry) {\n  return entry != null && entry.size() >= 2 && entry.get(0) instanceof Integer;\n}","tryCatchPattern":"try {\n  verifySubjectAltNameInLeaf(certificate, sanList);\n} catch (CertificateParsingException e) {\n  logger.warn(\"Peer certificate has malformed SAN; treating as untrusted: \" + e.getMessage());\n  return false; // fail verification, do not crash handshake\n}","preventionTips":["Use well-formed certificates (SAN entries as type+value pairs)","Keep security providers current to avoid parser quirks","Inspect suspect certificates with openssl x509 -text"],"tags":["xds","tls","certificate","san"],"backgroundTag":"invalid-argument-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"}