The information contained in this article has been verified as up-to-date on the date of the original publication of the article. HashiCorp endeavors to keep this information up-to-date and correct, but it makes no representations or warranties of any kind, express or implied, about the ongoing completeness, accuracy, reliability, or suitability of the information provided.
All information contained in this article is for general information purposes only. Any reliance you place on such information as it applies to your use of your HashiCorp product is therefore strictly at your own risk.
Overview
This article explains the cause of a common Consul error related to protocol mismatch in discovery chains during the update or deletion of config entries. You can follow these steps to resolve the problem.
Issue Description
When trying to delete a service-defaults config entry using the Consul CLI or API, you may encounter an error similar to:
Error: failed to delete 'api-v1' config entry: Unexpected response code: 500 (discovery chain "api" uses inconsistent protocols; service "api-v1" has "tcp" which is not "http")
The failure typically occurs when attempting to delete or update a service-defaults config entry for a service that is still referenced by an upstream config like a service-router or ingress-gateway, resulting in a temporary protocol mismatch that Consul blocks to prevent invalid configurations.
Consul enforces strict validation on config entries to ensure consistent traffic routing. Services is defaulted to the "tcp" protocol unless explicitly set to "http". When a service-router config entry(or similar configs like ingress-gateway) references a downstream service and uses HTTP-specific features, the entire discovery chain must align on compatible protocols.
Deleting a service-defaults entry reverts the service's protocol to "tcp". If an upstream config (e.g., service-router) still references that service, Consul detects the protocol mismatch and block the operation with a 500 error.
Scenario
Here is an example scenario:
1. A service-defaults entry for the main service ("api") with HTTP protocol.
Kind = "service-defaults"
Name = "api"
Protocol = "http"
2. Another service-defaults entry for the destination service ("api-v1") with HTTP protocol
Kind = "service-defaults"
Name = "api-v1"
Protocol = "http"
3. Create a service-router for "api" referencing "api-v1".
Kind = "service-router"
Name = "api"
Routes = [
{
Match = {
HTTP = {
PathPrefix = "/v1"
}
}
Destination = {
Service = "api-v1"
}
}
]
Attempted Deletion
Attempt to delete the service-defaults for "api-v1" or update the protocol to "tcp"
$ consul config delete -kind service-defaults -name api-v1
This fails with the protocol mismatch error as showed above, because the service-router still references "api-v1" in the Routes block
Solution
To resolve, first update the upstream config service-router to remove the reference to the downstream service, then delete the service-defaults. This breaks the dependency, allowing Consul's validation to pass.
1. Remove the "api-v1" service from the service-router Routes block.
Kind = "service-router"
Name = "api"
Routes = []
2. Then update the service-router config entry
$ consul config write SERVICE_ROUTER
3. Now delete the service-defaults
$ consul config delete -kind service-defaults -name api-v1
Now, you should be able to delete the config entry without encountering protocol mismatch errors.
This behavior is intentional in Consul to maintain routing integrity. Similar issues can occur with other interdependent configs, such as ingress-gateway listeners referencing services. If you face any issues, feel free to reach out to our support team for further assistance.
References
- Service defaults configuration reference
- Service router configuration reference
- Ingress gateway configuration entry reference