Configuration can now specify different Cross-Origin Resource Sharing (CORS) rules for different origins using the cors.policies key. See the CORS documentation for details.
cors:
policies:
# The default CORS options work for Studio.
- origins: ["https://studio.apollographql.com"]
# Specific config for trusted origins
- match_origins: ["^https://(dev|staging|www)?\\.my-app\\.(com|fr|tn)$"]
allow_credentials: true
allow_headers: ["content-type", "authorization", "x-web-version"]
# Catch-all for untrusted origins
- origins: ["*"]
allow_credentials: false
allow_headers: ["content-type"]
By @Velfi in https://github.com/apollographql/router/pull/7853
This PR adds the following new metrics when running the router on Linux with its default global-allocator feature:
munmap(2) or similar.By @Velfi in https://github.com/apollographql/router/pull/7735
The router was creating invalid GraphQL responses internally, especially when subscriptions terminate. When a coprocessor is configured, it validates all responses for correctness, causing errors to be logged when the router generates invalid internal responses. This affects the reliability of subscription workflows with coprocessors.
Fix handling of invalid GraphQL responses returned from coprocessors, particularly when used with subscriptions. Added conditional response validation and improved testing to ensure correctness. Added the response_validation configuration option at the coprocessor level to enable the response validation (by default it's enabled).
By @BrynCooke in https://github.com/apollographql/router/pull/7731
Fixes a regression introduced in v1.50.0. When multiple client subscriptions are deduped onto a single subgraph subscription in WebSocket passthrough mode, and the first client subscription closes, the Router would close the subgraph subscription. The other deduplicated subscriptions would then silently stop receiving events.
Now outgoing subscriptions to subgraphs are kept open as long as any client subscription uses them.
By @bnjjj in https://github.com/apollographql/router/pull/7879
When a hot reload is triggered by a configuration change, the router attempted to apply updated configuration to open subscriptions. This could cause excessive logging.
When a hot reload was triggered by a schema change, the router closed subscriptions with a SUBSCRIPTION_SCHEMA_RELOAD error. This happened before the new schema was fully active and warmed up, so clients could reconnect to the old schema, which should not happen.
To fix these issues, a configuration and a schema change now have the same behavior. The router waits for the new configuration and schema to be active, and then closes all subscriptions with a SUBSCRIPTION_SCHEMA_RELOAD/SUBSCRIPTION_CONFIG_RELOAD error, so clients can reconnect.
By @goto-bus-stop and @bnjjj in https://github.com/apollographql/router/pull/7777
When trying to remove non-UTF-8 headers from a Rhai plugin, users were faced with an unhelpful error. Now, non-UTF-8 values will be lossy converted to UTF-8 when accessed from Rhai. This change affects get, get_all, and remove operations.
By @Velfi in https://github.com/apollographql/router/pull/7801
The router now correctly generates query plans when using progressive override (@override with labels) on types that implement interfaces within the same subgraph. Previously, the Rust query planner would fail to generate plans for these scenarios with the error "Was not able to find any options for {}: This shouldn't have happened.", while the JavaScript planner handled them correctly.
This fix resolves planning failures when your schema uses:
The router will now successfully plan and execute queries that previously resulted in query planning errors.
By @TylerBloom in https://github.com/apollographql/router/pull/7929
When the Persisted Queries feature is enabled, the router no longer hangs during startup when using a GraphOS account with no Persisted Queries manifest.
@ from error paths (Issue #4548)When a subgraph returns an unexpected response (ie not a body with at least one of errors or data), the errors surfaced by the router include an @ in the path which indicates an error applied to all elements in the array. This is not a behavior defined in the GraphQL spec and is not easily parsed.
This fix expands the @ symbol to reflect all paths that the error applies to.
Consider a federated graph with two subgraphs, products and inventory, and a topProducts query which fetches a list of products from products and then fetches an inventory status for each product.
A successful response might look like:
{
"data": {
"topProducts": [
{"name": "Table", "inStock": true},
{"name": "Chair", "inStock": false}
]
}
}
Prior to this change, if the inventory subgraph returns a malformed response, the router response would look like:
{
"data": {"topProducts": [{"name": "Table", "inStock": null}, {"name": "Chair", "inStock": null}]},
"errors": [
{
"message": "service 'inventory' response was malformed: graphql response without data must contain at least one error",
"path": ["topProducts", "@"],
"extensions": {"service": "inventory", "reason": "graphql response without data must contain at least one error", "code": "SUBREQUEST_MALFORMED_RESPONSE"}
}
]
}
With this change, the response will look like:
{
"data": {"topProducts": [{"name": "Table", "inStock": null}, {"name": "Chair", "inStock": null}]},
"errors": [
{
"message": "service 'inventory' response was malformed: graphql response without data must contain at least one error",
"path": ["topProducts", 0],
"extensions": {"service": "inventory", "reason": "graphql response without data must contain at least one error", "code": "SUBREQUEST_MALFORMED_RESPONSE"}
},
{
"message": "service 'inventory' response was malformed: graphql response without data must contain at least one error",
"path": ["topProducts", 1],
"extensions": {"service": "inventory", "reason": "graphql response without data must contain at least one error", "code": "SUBREQUEST_MALFORMED_RESPONSE"}
}
]
}
The above examples reflect the behavior with include_subgraph_errors = true; if include_subgraph_errors is false:
{
"data": {"topProducts": [{"name": "Table", "inStock": null}, {"name": "Chair", "inStock": null}]},
"errors": [
{
"message": "Subgraph errors redacted",
"path": ["topProducts", 0]
},
{
"message": "Subgraph errors redacted",
"path": ["topProducts", 1]
}
]
}
By @carodewig in https://github.com/apollographql/router/pull/7684
The APOLLO_TELEMETRY_DISABLED environment variable only disables anonymous telemetry, it was never meant for disabling identifiable telemetry. This includes metrics from the fleet detection plugin.
By @DMallare in https://github.com/apollographql/router/pull/7907
Fetched April 11, 2026