{"record":{"id":"12162c5556d409fd","repo":"grpc/grpc-java","slug":"invalid-san-entry-null-altnametype","errorCode":null,"errorMessage":"Invalid SAN entry: null altNameType","messagePattern":"Invalid SAN entry: null altNameType","errorType":"validation","errorClass":"CertificateParsingException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/internal/security/trust/XdsX509TrustManager.java","lineNumber":184,"sourceCode":"  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 {\n    Collection<List<?>> names = cert.getSubjectAlternativeNames();\n    if (names == null || names.isEmpty()) {\n      throw new CertificateException(\"Peer certificate SAN check failed\");\n    }","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/internal/security/trust/XdsX509TrustManager.java#L166-L202","documentation":"After the structural check, verifyOneSanInList casts entry.get(0) to Integer (the SAN type) and requires it to be non-null before switching on ALT_DNS_NAME / ALT_URI_NAME / ALT_IPA_NAME. If the first element is null, it throws CertificateParsingException('Invalid SAN entry: null altNameType'), meaning the parsed SAN entry lacks a usable type discriminator.","triggerScenarios":"Same path as the malformed-SAN case: certificate.getSubjectAlternativeNames() yields an entry whose first element is null — typically from a non-conforming security provider's parser or a corrupted/oddly encoded SAN extension.","commonSituations":"Custom or buggy X509Certificate implementations; certificates with empty/unparsable GeneralName entries; provider version bugs decoding SAN extensions into lists with null first elements.","solutions":["Replace the certificate with one whose SAN extension is well-formed (verify with openssl x509 -text)","Switch or update the security provider responsible for parsing the certificate (e.g. conscrypt/BouncyCastle version bump)","Catch CertificateParsingException during verification and treat the cert as untrusted rather than crashing","If parsing your own cert collections, ensure each entry is a non-null [Integer type, String value] pair"],"exampleFix":"// before: manual SAN list entries like Arrays.asList(null, \"foo.example.com\")\nList<?> entry = Arrays.asList(null, \"foo.example.com\");\n// after\nList<?> entry = Arrays.asList(2 /* ALT_DNS_NAME */, \"foo.example.com\");","handlingStrategy":"validation","validationCode":"// Ensure SAN entry type is a non-null Integer before switching\nboolean sanTypeKnown(List<?> entry) {\n  return entry != null && entry.size() >= 2 && entry.get(0) instanceof Integer\n      && entry.get(0) != null;\n}","typeGuard":"static boolean hasSanType(List<?> entry) {\n  return entry != null && entry.size() >= 2 && entry.get(0) instanceof Integer && entry.get(0) != null;\n}","tryCatchPattern":"try {\n  verifySubjectAltNameInLeaf(certificate, sanList);\n} catch (CertificateParsingException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"null altNameType\")) {\n    logger.error(\"SAN entry missing type; check certificate/provider parser\", e);\n  }\n  throw e;\n}","preventionTips":["Regenerate certificates with valid SAN GeneralName entries","Update/replace security providers that decode SAN types as null","Build test certs with correct ALT_DNS_NAME/ALT_IPA_NAME types in tests"],"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"}