Apollo Router Changelogs
This page contains the changelog for the latest release of Apollo Router.
Go to GitHub to view changelogs for all router releases.
v2.4.0
π Features
Support JWT audience (aud
) validation (PR #7578)
The router now supports JWT audience (aud
) validation. This allows the router to ensure that the JWT is intended
for the specific audience it is being used with, enhancing security by preventing token misuse across different audiences.
The following sample configuration will validate the JWT's aud
claim against the specified audiences and ensure a match with either https://my.api
or https://my.other.api
. If the aud
claim does not match either of those configured audiences, the router will reject the request.
authentication:
router:
jwt:
jwks: # This key is required.
- url: https://dev-zzp5enui.us.auth0.com/.well-known/jwks.json
issuers: # optional list of issuers
- https://issuer.one
- https://issuer.two
audiences: # optional list of audiences
- https://my.api
- https://my.other.api
poll_interval: <optional poll interval>
headers: # optional list of static headers added to the HTTP request to the JWKS URL
- name: User-Agent
value: router
# These keys are optional. Default values are shown.
header_name: Authorization
header_value_prefix: Bearer
on_error: Error
# array of alternative token sources
sources:
- type: header
name: X-Authorization
value_prefix: Bearer
- type: cookie
name: authz
Prioritize existing requests over query parsing and planning during "warm up" (PR #7223)
The router warms up its query planning cache during a hot reload. This change decreases the priority of warm up tasks in the compute job queue to reduce the impact of warmup on serving requests.
This change adds new values to the job.type
dimension of the following metrics:
apollo.router.compute_jobs.duration
- A histogram of time spent in the compute pipeline by the job, including the queue and query planning.job.type
: (query_planning
,query_parsing
,introspection
,query_planning_warmup
,query_parsing_warmup
)job.outcome
: (executed_ok
,executed_error
,channel_error
,rejected_queue_full
,abandoned
)
apollo.router.compute_jobs.queue.wait.duration
- A histogram of time spent in the compute queue by the job.job.type
: (query_planning
,query_parsing
,introspection
,query_planning_warmup
,query_parsing_warmup
)
apollo.router.compute_jobs.execution.duration
- A histogram of time spent to execute job (excludes time spent in the queue).job.type
: (query_planning
,query_parsing
,introspection
,query_planning_warmup
,query_parsing_warmup
)
apollo.router.compute_jobs.active_jobs
- A gauge of the number of compute jobs being processed in parallel.job.type
: (query_planning
,query_parsing
,introspection
,query_planning_warmup
,query_parsing_warmup
)
Persisted queries: include operation name in PERSISTED_QUERY_NOT_IN_LIST
error for debuggability (PR #7768)
When persisted query safelisting is enabled and a request has an unknown PQ ID, the GraphQL error now has the extension field operation_name
containing the GraphQL operation name (if provided explicitly in the request). Note that this only applies to the PERSISTED_QUERY_NOT_IN_LIST
error returned when manifest-based PQs are enabled, APQs are disabled, and the request contains an operation ID that is not in the list.
Introduce cooperative cancellation for query planning
The cooperative cancellation feature allows the router to gracefully handle query planning timeouts and cancellations, improving resource utilization.
The mode
can be set to measure
or enforce
. We recommend starting with measure
. In measure
mode, the router will measure the time taken for query planning and emit metrics accordingly. In enforce
mode, the router will cancel query planning operations that exceed the specified timeout.
To observe this behavior, the router telemetry has been updated:
- Add an
outcome
attribute to theapollo.router.query_planning.plan.duration
metric - Add an
outcome
attribute to thequery_planning
span
Below is a sample configuration to configure cooperative cancellation in measure mode:
supergraph:
query_planning:
experimental_cooperative_cancellation:
enabled: true
mode: measure
timeout: 1s
π Fixes
Align on_graphql_error
selector with subgraph_on_graphql_error
(PR #7676)
The on_graphql_error
selector will now return true
or false
, in alignment with the subgraph_on_graphql_error
selector. Previously, the selector would return true
or None
.
Return valid GraphQL response when performing a websocket handshake (PR #7680)
PR #7141 added checks on GraphQL responses returned from coprocessors to ensure compliance with GraphQL specifications. This surfaced an issue where subscription responses over websockets could omit the required data
field during the handshake, resulting in invalid GraphQL response payloads. All websocket subscription responses will now return a valid GraphQL response when doing the websocket handshake.
Fix SigV4 configuration handling (PR #7726)
Fixed an issue introduced in Router 2.3.0 where some SigV4 configurations would fail to start, preventing communication with SigV4-enabled services.
Improve error message for invalid variables (Issue #2984)
When a variable in a GraphQL request is missing or contains an invalid value, the router now returns more useful error messages. Example:
-invalid type for variable: 'x'
+invalid input value at x.coordinates[0].longitude: found JSON null for GraphQL Float!
Support exporting resources on all Prometheus metrics (PR #7394)
By default, the Prometheus metrics exporter will only export resources as target_info
metrics, not inline on every metric. Now, you can add resources to every metric by setting resource_selector
to all
(default is none
).
telemetry:
exporters:
metrics:
common:
resource:
"test-resource": "test"
prometheus:
enabled: true
resource_selector: all # This will add resources on every metrics
Note: this change only affects Prometheus, not OTLP.
Forbid unknown @link
directives for supergraph schemas where purpose
is EXECUTION
or SECURITY
The legacy JavaScript query planner forbid any usage of unknown @link
specs in supergraph schemas with either EXECUTION
or SECURITY
value set for the for
argument (aka, the spec's "purpose"). This behavior had not been ported to the native query planner previously. This PR implements the expected behavior in the native query planner.
Supergraph stage correctly receives on_graphql_error
selector (PR #7669)
The on_graphql_error
selector will now correctly fire on the supergraph stage; previously it only worked on the router stage.
Invalid type condition in @defer
fetch
The query planner was adding an inline spread (...
) conditioned on the Query
type in deferred subgraph fetch queries. Such a query would be invalid in the subgraph when the subgraph schema renamed the root query
type to somethhing other than Query
. The fix removes the root type condition from all subgraph queries, so that they stay valid even when root types are renamed.
Preserve content-type
for file uploads when Rhai scripts are in use (PR #7559)
If a Rhai script was invoked during file upload processing, then the "Content-Type" of the request was not preserved correctly. This would cause a file upload to fail.
The error message would be something like:
"message": "invalid multipart request: Content-Type is not multipart/form-data",
This issue has now been fixed.
Improve OTLP metric HTTP endpoint behavior (PR #7595)
We made substantial updates to OpenTelemetry in router 2.0, but didn't catch that OpenTelemetry changed how it processed "endpoints" (destinations for metrics and traces) until now.
With the undetected change, the router wasn't setting the path correctly, resulting in failure to export metrics over HTTP when using the "default" endpoint. Neither metrics via gRPC nor traces were impacted.
We have fixed our interactions with the dependency and improved our testing to make sure this does not occur again. Additionally, the router now supports setting standard OpenTelemetry environment variables for endpoints.
There is still a known problem when using environment variables to configure endpoints for the HTTP protocol when transmitting to an un-encrypted endpoint (i.e., TLS not configured). This affects the following environment variables:
OTEL_EXPORTER_OTLP_ENDPOINT
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
When these environment variables are set to insecure hosts, messages will appear in the logs indicating an error, but the metrics and traces will still be sent correctly:
2025-06-06T15:12:47.992144Z ERROR OpenTelemetry metric error occurred: Metrics exporter otlp failed with the grpc server returns error (Unknown error): , detailed error message: h2 protocol error: http2 error tonic::transport::Error(Transport, hyper::Error(Http2, Error { kind: GoAway(b"", FRAME_SIZE_ERROR, Library) }))
2025-06-06T15:12:47.992763Z ERROR OpenTelemetry trace error occurred: Exporter otlp encountered the following error(s): the grpc server returns error (Unknown error): , detailed error message: h2 protocol error: http2 error tonic::transport::Error(Transport, hyper::Error(Http2, Error { kind: GoAway(b"", FRAME_SIZE_ERROR, Library) }))
This is tracked upstream at https://github.com/open-telemetry/opentelemetry-collector/issues/10952.
Add graphql.operation.name
attribute to apollo.router.opened.subscriptions
counter (PR #7606)
The apollo.router.opened.subscriptions
metric has an graphql.operation.name
attribute applied to identify the named operation of open subscriptions.
π Maintenance
Measure preview_extended_error_metrics
in Apollo config telemetry (PR #7597)
π Documentation
Document Apollo Runtime Container deployment (PR #7734 and PR #7668)
The Apollo Runtime Container is now included in our documentation for deployment options. It also includes instructions for running Apollo Router with the Apollo MCP Server.
Fix incorrect reference to apollo.router.schema.load.duration
(PR #7582)
The in-memory cache documentation was referencing an incorrect metric to track schema load times. Previously it was referred to as apollo.router.schema.loading.time
, whereas the metric being emitted by the router since v2.0.0 is actually apollo.router.schema.load.duration
. This is now fixed.