Skip to content

Generated xDS configuration rewrites path wrong when using a path prefix match rule in a http-route #23339

@aft2d

Description

@aft2d

Overview of the Issue

The generated xDS configuration removes the prefix from the path when using a prefix-match rule in an http-route configuration.

My http-route configuration looks like this:

...
"Rules": [
  {
    "Matches": [
      {
        "Path": {
          "Match": "prefix",
          "Value": "/v2"
        },
      }
    ],
    "Services": [
      {
        "Name": "v2-service",
      }
    ]
  },
  {
    "Services": [
      {
        "Name": "v1-service",
      }
    ]
  }
],
...

The intended behavior is that requests whose path begins with /v2 are routed to the v2 service and all others to the v1 service. The paths should remain unaltered in any case.

In Consul v1.21.5, the rendered xDS configuration looked like this:

...
"routes": [
  {
    "match": {
      "prefix": "/v2"
    },
    "route": {
      "cluster": "v2-service.default.dc1.internal.c9b287e7-24b9-4f65-91fa-3c186517a018.consul",
      "timeout": "120s"
    }
  },
  {
    "match": {
      "prefix": "/"
    },
    "route": {
      "cluster": "v1-service.default.dc1.internal.c9b287e7-24b9-4f65-91fa-3c186517a018.consul"
    }
  }
]
  ...

In Consul v1.22.5, the rendered xDS configuration looks like this:

...
"routes": [
  {
    "match": {
      "prefix": "/v2"
    },
    "route": {
      "cluster": "v2-service.default.dc1.internal.c9b287e7-24b9-4f65-91fa-3c186517a018.consul",
      "timeout": "120s",
      "regex_rewrite": {
        "pattern": {
          "regex": "^/v2(/?)(.*)"
        },
        "substitution": "/\\2"
      }
    }
  },
  {
    "match": {
      "prefix": "/"
    },
    "route": {
      "cluster": "v1-service.default.dc1.internal.c9b287e7-24b9-4f65-91fa-3c186517a018.consul",
      "regex_rewrite": {
        "pattern": {
          "regex": "^/(/?)(.*)"
        },
        "substitution": "/\\2"
      }
    }
  }
]
...

The result is that the upstream service receives a request with the wrong path:

request as sent by the client request as received by the backend service
example.com/v2/test example.com/test
example.com/v1/test example.com/v1/test

You can see that the substitution uses matching group two from the regex, which doesn't contain the prefix path.
To me, it seems that either the matching groups must be adjusted or the substitution field should also contain the prefix.
If I'm not mistaken, the source of this issue comes from this PR: #23035


Reproduction Steps

Steps to reproduce this issue, eg:

  1. Create a Consul Mesh setup with an API-Gateway
  2. Create an http-route configuration with a path-prefix matching rule like in the example above
  3. run requests through this http-route and observe the requests paths and xDS configuration as explained above

Consul info for both Client and Server

Server & Client

Consul v1.22.5
Revision 3a6dbfc4
Build Date 2026-02-26T11:50:53Z
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)

Operating system and Environment details

Ubuntu 24.04.2 LTS
Consul installed from the HashiCorp APT repo

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions