{"record":{"id":"55c853418349560a","repo":"grpc/grpc-java","slug":"verify-certificate-hash-in-default-validation-cont","errorCode":null,"errorMessage":"verify_certificate_hash in default_validation_context is not supported","messagePattern":"verify_certificate_hash in default_validation_context is not supported","errorType":"validation","errorClass":"ResourceInvalidException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/XdsClusterResource.java","lineNumber":515,"sourceCode":"        certificateValidationContext = commonTlsContext.getValidationContext();\n      } else if (commonTlsContext.hasCombinedValidationContext() && commonTlsContext\n          .getCombinedValidationContext().hasDefaultValidationContext()) {\n        certificateValidationContext = commonTlsContext.getCombinedValidationContext()\n            .getDefaultValidationContext();\n      }\n      if (certificateValidationContext != null) {\n        @SuppressWarnings(\"deprecation\") // gRFC A29 predates match_typed_subject_alt_names\n        int matchSubjectAltNamesCount = certificateValidationContext.getMatchSubjectAltNamesCount();\n        if (matchSubjectAltNamesCount > 0 && server) {\n          throw new ResourceInvalidException(\n              \"match_subject_alt_names only allowed in upstream_tls_context\");\n        }\n        if (certificateValidationContext.getVerifyCertificateSpkiCount() > 0) {\n          throw new ResourceInvalidException(\n              \"verify_certificate_spki in default_validation_context is not supported\");\n        }\n        if (certificateValidationContext.getVerifyCertificateHashCount() > 0) {\n          throw new ResourceInvalidException(\n              \"verify_certificate_hash in default_validation_context is not supported\");\n        }\n        if (certificateValidationContext.hasRequireSignedCertificateTimestamp()) {\n          throw new ResourceInvalidException(\n              \"require_signed_certificate_timestamp in default_validation_context is not \"\n                  + \"supported\");\n        }\n        if (certificateValidationContext.hasCrl()) {\n          throw new ResourceInvalidException(\"crl in default_validation_context is not supported\");\n        }\n        if (certificateValidationContext.hasCustomValidatorConfig()) {\n          throw new ResourceInvalidException(\n              \"custom_validator_config in default_validation_context is not supported\");\n        }\n      }\n    }\n  }\n","sourceCodeStart":497,"sourceCodeEnd":533,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/XdsClusterResource.java#L497-L533","documentation":"gRPC xDS rejects a CertificateValidationContext whose default_validation_context contains verify_certificate_hash entries. Certificate-hash (SHA256 fingerprint) pinning is not supported by grpc-java's xDS transport security, so any cluster resource carrying it fails validation with ResourceInvalidException.","triggerScenarios":"A CDS Cluster resource's upstream_tls_context -> common_tls_context -> validation_context.default_validation_context sets verify_certificate_hash (one or more cert fingerprints), reaching validateCommonTlsContext via validateUpstreamTlsContext.","commonSituations":"Porting Envoy TLS configs that pin server certificates by hash; security teams adding fingerprint pinning per policy; generated control-plane configs that include hash pins unconditionally.","solutions":["Remove verify_certificate_hash from default_validation_context","Rely on root-of-trust validation via trust_ca / ca_certificate_provider_file","Constrain server identity with match_subject_alt_names (allowed upstream only)","Use SDS with proper cert validation rather than static fingerprints"],"exampleFix":"// before\ndefault_validation_context {\n  verify_certificate_hash: \"aabbcc...\"\n}\n// after\ndefault_validation_context {}\ntrust_ca { ... }\nmatch_subject_alt_names { prefix: \"expected.name\" }","handlingStrategy":"validation","validationCode":"if (ctx.getDefaultValidationContext().getVerifyCertificateHashCount() > 0) {\n  throw new IllegalArgumentException(\"verify_certificate_hash unsupported by grpc-java xDS\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  cluster = XdsClusterResource.parse(resource);\n} catch (ResourceInvalidException e) {\n  // fall back to last-known-good cluster config\n}","preventionTips":["Use CA-based trust (trust_ca) rather than certificate fingerprint pinning","Constrain peers via match_subject_alt_names in upstream contexts","Audit control-plane generators for Envoy-only fields","Pin at issuance/distribution, not in xDS config"],"tags":["xds","grpc-java","mtls","tls","certificate-pinning"],"backgroundTag":"unsupported-config-value","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"}