• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

grpc / grpc-java / #20507
89%

Build:
DEFAULT BRANCH: master
Ran 08 Oct 2026 06:11AM UTC
Jobs 1
Files 697
Run time 2min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

08 Oct 2026 06:00AM UTC coverage: 89.396% (+0.02%) from 89.378%
#20507

push

github

web-flow
xDS: fix DistributorWatcher thread safety in CertificateProvider (#13087)

A gRPC client using xDS-driven mTLS does two things concurrently:

1. Certificate provider: watches cert files on disk, periodically
reloads them, and notifies subscribers when certs change.
2. Channel subscriptions: each gRPC channel that needs mTLS registers a
watcher on the cert provider to get the TLS credentials.

The `DistributorWatcher` sits in the middle and fans out: one cert
provider pushes updates to it, and it distributes to N channel watchers.

I think there are two conditions in this that can lead to a
`ConcurrentModificationException`:

1. `updateSpiffeTrustMap` isn't synchronized (unlike `updateCertificate`
and `updateTrustedRoots`), so it can race against
`addWatcher`/`removeWatcher` from another thread.
2. if callbacks mutate their own subscription. A callchain (line numbers
per 1.83.0 / 1084e9707) for that is:

```
  DistributorWatcher.onError()                              CertificateProvider.java:126
    → for (watcher : downstreamWatchers)                    CertificateProvider.java:127
      → watcher.onError(errorStatus)                        CertificateProvider.java:128
        → DynamicSslContextProvider.onError()               DynamicSslContextProvider.java:143
          → callback.onException(error)                     DynamicSslContextProvider.java:145
            → SslContextProviderSupplier.onException()      SslContextProviderSupplier.java:79
              → releaseSslContextProvider(toRelease)        SslContextProviderSupplier.java:81
                → TlsContextManagerImpl.releaseClient...()  TlsContextManagerImpl.java:78
                  → ReferenceCountingMap.releaseInternal()  ReferenceCountingMap.java:89
                    → if refcount == 0: value.close()       ReferenceCountingMap.java:95
                      → CertProviderSslContextProvider.close()  CertProviderSslContextProvider.java:216
                        → certHandle.close() ... (continued)

39327 of 43992 relevant lines covered (89.4%)

0.89 hits per line

Coverage Regressions

Lines Coverage ∆ File
2
90.63
-0.35% ../core/src/main/java/io/grpc/internal/DelayedClientCall.java
2
88.89
-11.11% ../netty/src/main/java/io/grpc/netty/UdsNameResolver.java
1
93.24
-0.14% ../okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java
1
87.6
-0.83% ../rls/src/main/java/io/grpc/rls/LinkedHashLruCache.java
1
98.68
2.13% ../xds/src/main/java/io/grpc/xds/internal/security/certprovider/CertificateProvider.java
Jobs
ID Job ID Ran Files Coverage
1 #20507.1 08 Oct 2026 06:11AM UTC 697
89.4
Source Files on build #20507
  • Tree
  • List 697
  • Changed 10
  • Source Changed 0
  • Coverage Changed 10
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #20507
  • 341f82c2 on github
  • Prev Build on master
  • Next Build on master
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc