Dissecting Spotify's Global Outage: Service Discovery, GCP Traffic Director, and gRPC Failure Modes

Arpit Bhayani

Arpit Bhayani

Mar 12, 2022 • 8 min read

Play

Dissecting Spotify’s Global Outage: Service Discovery, GCP Traffic Director, and gRPC Failure Modes

On March 8, 2022, Spotify experienced a massive, high-profile global outage. Users worldwide found themselves abruptly logged out of their mobile and desktop clients, unable to log back in.

Initial industry speculation pointed toward a systemic failure in Spotify’s authentication service or an outage within their session/token caching layer (such as Redis or Memcached). However, when Spotify and Google Cloud Platform (GCP) released their official incident reports, the post-mortem revealed a far more nuanced, multi-layered systems failure involving cloud-hosted service discovery, the xDS protocol, and a subtle error propagation bug in Java’s gRPC client library.


1. The Anatomy of Service Discovery at Scale

In a distributed microservices topology, dozens or hundreds of independent services need to discover and communicate with each other synchronously and asynchronously. When an end-user action spans authentication, playlist hydration, search, and audio streaming, microservices must route requests across dynamically scaling compute pools.

Historically, systems relied on static URLs fronted by infrastructure load balancers. Over time, high-throughput architectures evolved into service meshes.

Model A: DNS-Based Routing (Traditional Load Balancing)

In a traditional DNS-based setup:

  • Each service is assigned an internal domain name (e.g., payments.spotify.net or auth.spotify.internal).
  • A network or application load balancer (NLB/ALB) sits in front of the application instances.
  • Requesting services resolve the domain name through internal DNS and send requests to the load balancer, which distributes traffic across healthy instances.
+------------------+         DNS Lookup        +---------------+ 
|  Stream Service  | ------------------------> | Internal DNS  |
+------------------+                           +---------------+ 
         |                                             |
         | HTTP / REST (auth.spotify.internal)         | IP of LB
         v                                             v
+--------------------+      Forward      +------------------------+
|   Load Balancer    | ----------------> | Auth Instance (Pod 1)  |
+--------------------+                   +------------------------+
                                         | Auth Instance (Pod 2)  |
                                         +------------------------+

Trade-offs of DNS-based routing:

  • Pros: Simple to operate, language-agnostic, works cleanly out-of-the-box with standard networking stacks.
  • Cons: Extra network hops through load balancers, DNS caching/TTL issues during rapid scaling, lack of fine-grained client-side load balancing, and duplicated operational logic (retries, timeouts, circuit breaking) inside every client service.

Model B: Service Mesh and the Sidecar Pattern

In a service mesh architecture (e.g., Envoy, Istio), operational concerns are removed entirely from the application source code and delegated to a dedicated proxy process running alongside the application container—the sidecar.

+------------------------------------+       +------------------------------------+
| Host A                             |       | Host B                             |
|  +------------------------------+  |       |  +------------------------------+  |
|  | Authentication Service       |  |       |  | Streaming Service            |  |
|  | (Business Logic)             |  |       |  | (Business Logic)             |  |
|  +------------------------------+  |       |  +------------------------------+  |
|                 | Localhost        |       |                 ^ Localhost        |
|                 v (Port 8000)      |       |                 |                  |
|  +------------------------------+  |  mTLS |  +------------------------------+  |
|  | Sidecar Proxy (e.g., Envoy)  | -|-------|->| Sidecar Proxy (e.g., Envoy)  |  |
|  +------------------------------+  |  xDS  |  +------------------------------+  |
+------------------------------------+       +------------------------------------+
                   ^                                            ^
                   | Dynamic Configuration Updates (xDS)        |
                   +--------------------+-----------------------+
                                        |
                             +--------------------+
                             |   Control Plane    |
                             | (Traffic Director) |
                             +--------------------+

Instead of writing custom retry loops, timeout configurations, distributed tracing instrumentation, and TLS termination within each microservice codebase, the sidecar intercepts ingress and egress traffic. When Service A wants to call Service B:

  1. Service A sends the request to its local sidecar on localhost.
  2. The sidecar determines which specific IP address of Service B to connect to, handling load balancing, mTLS, timeouts, and circuit breaking.
  3. The sidecar on Host A transmits the request to the sidecar on Host B, which hands it off to Service B’s local business process.

2. Control Planes and the xDS Protocol

For sidecars to know where remote instances live without hardcoded configurations, they rely on a Control Plane via xDS (eXtensible Discovery Service) APIs.

  • Data Plane: The proxies (Envoy or gRPC client libraries acting as their own proxy) carrying the actual payload.
  • Control Plane: The centralized management system that tracks active instance IPs, health checks, routing rules, and canary configurations.

When a new instance boots up, it registers with the control plane. The control plane pushes dynamic updates down to every sidecar over an active streaming gRPC connection using xDS protocols (e.g., LDS for Listeners, RDS for Routes, CDS for Clusters, and EDS for Endpoints).

Rather than running a custom or self-hosted control plane, Spotify leveraged Google Cloud’s Traffic Director—a fully managed, enterprise-grade control plane that natively speaks xDS.


3. The Incident: March 8, 2022

The cascading failure that took down Spotify was not a single point of failure within their core business logic, but a dual fault triggered by a cloud provider incident combined with an SDK error propagation bug.

+---------------------------+
| GCP Rollout in us-east-1  |
+---------------------------+
              |
              v
+---------------------------+       Elevated 5xx / Broken Updates
|   GCP Traffic Director    | -----------------------------------------+
+---------------------------+                                         |
                                                                      v
                                                  +----------------------------------+
                                                  | Java gRPC xDS Name Resolver Bug  |
                                                  +----------------------------------+
                                                                      |
                                                                      | Swallows Cause,
                                                                      | Throws Generic NOT_FOUND
                                                                      v
                                                  +----------------------------------+
                                                  | Core Services Fail to Resolve    |
                                                  | Upstreams (Auth, Streaming, etc) |
                                                  +----------------------------------+
                                                                      |
                                                                      v
                                                  +----------------------------------+
                                                  | Global User Logouts & Failures   |
                                                  +----------------------------------+

Step 1: The GCP Traffic Director Degraded Rollout

During a rollout in GCP’s us-east1 region, a bad configuration deployment within Google Cloud Traffic Director caused elevated HTTP 5xx errors and broke resolution for managed backends. Envoy sidecars and gRPC clients using Traffic Director as an xDS control plane suddenly stopped receiving valid endpoint updates.

Step 2: The Java gRPC Client Library Bug

Spotify heavily utilizes gRPC in Java. In proxyless or sidecar-based gRPC deployments, the gRPC client uses an internal xDS Name Resolver to translate target service names into backends.

When an xDS client watch failed due to the Traffic Director outage, the Java gRPC library (grpc-java) suffered from a severe error handling regression:

// Simplified representation of the regression in grpc-java:

// BEFORE FIX (Buggy Behavior):
if (watchFailed) {
    // Propagated error verbatim to channel without contextual status or wrapping
    channel.onError(rawError); 
    // Downstream caller received a misleading Status.NOT_FOUND without actionable context
}

// AFTER FIX (grpc-java 1.45.0):
if (watchFailed) {
    Status status = Status.UNAVAILABLE
        .withDescription("Unable to load LDS/CDS/EDS from xDS server: " + rawError.getMessage())
        .withCause(rawError);
    channel.onError(status.asRuntimeException());
}

Because the name resolver did not mark the failure state properly with Status.UNAVAILABLE and provide the root cause, downstream calling systems could not gracefully catch the error, trigger fallback pathways, or back off and retry. Instead, service calls abruptly broke with unhandled exceptions, making upstream services (such as authentication) appear completely dead to the mobile and web clients.

Clients receiving unresolvable errors invalidated session state, triggering the forced logout of millions of users globally.


4. Mitigation and The Value of Hybrid Fallbacks

Google Cloud identified the issue and issued guidance:

“Customers with Traffic Director managing their backends should consider moving to backends that are not Traffic Director managed.”

Because Spotify had maintained a hybrid service discovery architecture—where portions of their legacy and critical workloads still operated using standard internal DNS-based routing—the engineering team was not forced to wait for GCP’s internal rollback.

Traffic Director Broken (Service Mesh Disabled)
              |
              v
[ Rapid Config Rollout: Switch Service Discovery Provider ]
              |
              v
DNS-Based Service Discovery (Load Balancers Active)
              |
              v
Service Resolution Restored (~2 to 2.5 hours post-outage)

Spotify engineers initiated a deployment that toggled affected microservices from xDS-based service discovery back to their proven DNS-based resolution mechanism. Services recovered progressively, fully restoring functionality within 2 to 2.5 hours.


5. Key Architecture and Reliability Engineering Lessons

1. Always Preserve Root-Cause Context in Error Handling

When writing internal libraries, proxies, or name resolvers, never swallow underlying error statuses or pass raw errors verbatim without domain context.

A network or control plane resolution issue is fundamentally an UNAVAILABLE transient condition, not an application-level NOT_FOUND. Misclassifying status codes prevents upstream resilient behaviors (e.g., retries, stale-cache reads, circuit breakers) from activating.

2. Multi-Tier Service Discovery as a Safeguard

Relying exclusively on a single cutting-edge control plane introduces a systemic single point of failure (SPOF). Spotify’s ability to recover was entirely due to having an operational fallback mechanism (DNS-based routing) already battle-tested in production.

3. Fail-Open / Cache Stale Configs on the Data Plane

A primary design rule of service meshes is that a failure of the control plane should not immediately take down the data plane:

  • If the control plane becomes unreachable, sidecars and client libraries should continue serving traffic using their last-known-good (stale) routing configuration.
  • Name resolvers must gracefully degrade to cached endpoint mappings rather than severing active transport channels.

4. Blast Radius Containment for Cloud Rollouts

Managed cloud services can and do fail. Resilient distributed systems must be architected with regional redundancy and clear runbooks that allow quick decoupling from managed control planes during major vendor-side incidents.

Arpit Bhayani

Principal Engineer II at Razorpay - building Agent Studio, Ex-staff engg at GCP Memorystore & Dataproc, Creator of DiceDB, ex-Amazon Fast Data, ex-Director of Engg. SRE and Data Engineering at Unacademy. I spark engineering curiosity through my no-fluff engineering videos on YouTube and my courses