grpc/grpc-java · error · ResourceInvalidException

match_subject_alt_names only allowed in upstream_tls_context

Error message

match_subject_alt_names only allowed in upstream_tls_context

What it means

Subject alternative name matching (match_subject_alt_names) is only supported on the client side (upstream_tls_context), where gRPC validates the server identity. Server-side (downstream) validation contexts cannot restrict client SANs, so a non-empty list in a server context invalidates the resource.

Source

Thrown at xds/src/main/java/io/grpc/xds/XdsClusterResource.java:507

    } else {
      if (certProviderInstances == null || !certProviderInstances.contains(rootCaInstanceName)) {
        throw new ResourceInvalidException(
            "ca_certificate_provider_instance name '" + rootCaInstanceName
                + "' not defined in the bootstrap file.");
      }
      CertificateValidationContext certificateValidationContext = null;
      if (commonTlsContext.hasValidationContext()) {
        certificateValidationContext = commonTlsContext.getValidationContext();
      } else if (commonTlsContext.hasCombinedValidationContext() && commonTlsContext
          .getCombinedValidationContext().hasDefaultValidationContext()) {
        certificateValidationContext = commonTlsContext.getCombinedValidationContext()
            .getDefaultValidationContext();
      }
      if (certificateValidationContext != null) {
        @SuppressWarnings("deprecation") // gRFC A29 predates match_typed_subject_alt_names
        int matchSubjectAltNamesCount = certificateValidationContext.getMatchSubjectAltNamesCount();
        if (matchSubjectAltNamesCount > 0 && server) {
          throw new ResourceInvalidException(
              "match_subject_alt_names only allowed in upstream_tls_context");
        }
        if (certificateValidationContext.getVerifyCertificateSpkiCount() > 0) {
          throw new ResourceInvalidException(
              "verify_certificate_spki in default_validation_context is not supported");
        }
        if (certificateValidationContext.getVerifyCertificateHashCount() > 0) {
          throw new ResourceInvalidException(
              "verify_certificate_hash in default_validation_context is not supported");
        }
        if (certificateValidationContext.hasRequireSignedCertificateTimestamp()) {
          throw new ResourceInvalidException(
              "require_signed_certificate_timestamp in default_validation_context is not "
                  + "supported");
        }
        if (certificateValidationContext.hasCrl()) {
          throw new ResourceInvalidException("crl in default_validation_context is not supported");
        }

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Remove match_subject_alt_names entries from the server-side validation context; authenticate clients via cert-provider-backed validation or application-level auth.
  2. Keep match_subject_alt_names only in upstream_tls_context where client-side server-identity checking is done.
  3. If peer identity enforcement is required server-side, use authorization (xDS RBAC/LDS) or in-process TLS peer verification via AuthContext after connection.

Example fix

// before (server downstream_tls_context)
"common_tls_context": {
  "tls_certificate_provider_instance": "server-certs",
  "combined_validation_context": { "default_validation_context": { "match_subject_alt_names": [ { "prefix": "spiffe://" } ] } }
}
// after
"common_tls_context": {
  "tls_certificate_provider_instance": "server-certs",
  "combined_validation_context": { "default_validation_context": {} }
}
Defensive patterns

Strategy: validation

Validate before calling

if (isServerContext && validationCtx.getMatchSubjectAltNamesCount() > 0) {
  throw new IllegalArgumentException("match_subject_alt_names only valid in upstream_tls_context");
}

Try / catch

catch (ResourceInvalidException e) {
  if (e.getMessage().contains("match_subject_alt_names only allowed")) {
    // regenerate server-side validation context without SAN matchers
  }
}

Prevention

When it happens

Trigger: server=true (downstream_tls_context validation) and certificateValidationContext.getMatchSubjectAltNamesCount() > 0 in validation_context, combined_validation_context's default, or default_validation_context (XdsClusterResource.java:507).

Common situations: Copying a client TLS context (with SAN allow-lists) into a server listener config; control planes that emit the same validation context template for both directions.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/f21b4c0117515e80. Report an issue: GitHub.