Skip to content

Breaking change in Consul CLI when registering a service with a schema in the address; Discrepancy between CLI and HTTP API behavior #23445

@Skylli202

Description

@Skylli202

Overview of the Issue

Reporting a breaking change on v1.21 introduced by this commit 6f87b06.

In our application, we are registering services with their full addresses. This includes the scheme, the hostname, and sometimes a path. This fully qualified URL is, in fact, a K8s ingress URL.

ℹ️ It is to be noted that while the CLI will prevent the registration of a service with an address that contains a scheme. The API HTTP handler will not behave the same way and happily accept an incoming request with a payload {"Name":"foo","Address":"https://foo.example.org"}. See more in the repro steps section.

I acknowledge that the undocumented breaking changes is most likely caused by an improper usage, or value, of the address field. But I hope that if this issue get categorized as Not a bug, I can receive help or guide line to solve my issue preventing me to upgrade.


Reproduction Steps

  1. Create a cluster in version v1.20 (any patch version; as of the day of writing, it is v1.20.6.)

I personnally simply create a single container using docker run hashicorp/consul:x.y.z.

  1. Run the CLI as consul services register -name foo -address https://foo.example.org.
  2. Observe the output:
$ docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED         STATUS         PORTS                                                        NAMES
6a3a40182027   hashicorp/consul:1.20   "docker-entrypoint.s…"   6 seconds ago   Up 5 seconds   8300-8302/tcp, 8500/tcp, 8301-8302/udp, 8600/tcp, 8600/udp   inspiring_mccarthy
$ docker exec 6a3a40182027 consul services register -name foo -address https://foo.example.org
Registered service: foo

Then

  1. Create a cluster in version v1.21.3 or above, v1.22.0 (or above), or v1.22.0 (or above).

As of the day of writing, latest patch version are respectively v1.21.7 and v1.22.6.

  1. Re-run the same CLI command and observe the output behave differently:
$ docker ps
CONTAINER ID   IMAGE                     COMMAND                  CREATED          STATUS          PORTS                                                        NAMES
42fbeaa21eca   hashicorp/consul:1.22.6   "docker-entrypoint.s…"   26 seconds ago   Up 25 seconds   8300-8302/tcp, 8500/tcp, 8301-8302/udp, 8600/tcp, 8600/udp   jolly_darwin
$ docker exec 42fbeaa21eca consul services register -name foo -address https://foo.example.org
Invalid Service address when using CLI flags. Use -port flag instead: address should not contain port
  1. Run a curl command to register the service with the payload {"Name":"foo","Address":"https://foo.example.org"} and see the happily registered service, which is a different behavior from the CLI.
$ docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED         STATUS         PORTS                                                                                           NAMES
2b48a05b8668   hashicorp/consul:1.22   "docker-entrypoint.s…"   3 minutes ago   Up 3 minutes   8300-8302/tcp, 8301-8302/udp, 8600/tcp, 8600/udp, 0.0.0.0:8500->8500/tcp, [::]:8500->8500/tcp   consul
$ docker exec 2b48a05b8668 curl -X PUT http://localhost:8500/v1/agent/service/register -H "Content-Type: application/json" -d '{"Name":"foo","Address":"https://foo.example.org"}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    50   0     0 100    50     0 28264  --:--:-- --:--:-- --:--:-- 50000
$ docker exec 2b48a05b8668 curl http://localhost:8500/v1/catalog/service/foo
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1100 100  1100   0     0  1424k     0  --:--:-- --:--:-- --:--:--  1074k
[
    {
        "ID": "e057088c-6117-aa9e-ee26-c016759ec181",
        "Node": "2b48a05b8668",
        "Address": "127.0.0.1",
        "Datacenter": "dc1",
        "TaggedAddresses": {
            "lan": "127.0.0.1",
            "lan_ipv4": "127.0.0.1",
            "wan": "127.0.0.1",
            "wan_ipv4": "127.0.0.1"
        },
        "NodeMeta": {
            "consul-network-segment": "",
            "consul-version": "1.22.6"
        },
        "ServiceKind": "",
        "ServiceID": "foo",
        "ServiceName": "foo",
        "ServiceTags": [],
        "ServiceAddress": "https://foo.example.org",
        "ServiceWeights": {
            "Passing": 1,
            "Warning": 1
        },
        "ServiceMeta": {},
        "ServicePort": 0,
        "ServicePorts": null,
        "ServiceSocketPath": "",
        "ServiceEnableTagOverride": false,
        "ServiceProxy": {
            "Mode": "",
            "MeshGateway": {},
            "Expose": {}
        },
        "ServiceConnect": {},
        "ServiceLocality": null,
        "CreateIndex": 18,
        "ModifyIndex": 18
    }
]% 

Consul info for both Client and Server

Client info
agent:
	check_monitors = 0
	check_ttls = 0
	checks = 0
	services = 0
build:
	prerelease = 
	revision = 97566680
	version = 1.22.6
	version_metadata = 
consul:
	acl = disabled
	bootstrap = false
	known_datacenters = 1
	leader = true
	leader_addr = 127.0.0.1:8300
	server = true
raft:
	applied_index = 19
	commit_index = 19
	fsm_pending = 0
	last_contact = 0
	last_log_index = 19
	last_log_term = 2
	last_snapshot_index = 0
	last_snapshot_term = 0
	latest_configuration = [{Suffrage:Voter ID:de5acb44-eede-0f78-956d-b77023788db7 Address:127.0.0.1:8300}]
	latest_configuration_index = 0
	num_peers = 0
	protocol_version = 3
	protocol_version_max = 3
	protocol_version_min = 0
	snapshot_version_max = 1
	snapshot_version_min = 0
	state = Leader
	term = 2
runtime:
	arch = arm64
	cpu_count = 10
	goroutines = 196
	max_procs = 10
	os = linux
	version = go1.25.8
serf_lan:
	coordinate_resets = 0
	encrypted = false
	event_queue = 1
	event_time = 2
	failed = 0
	health_score = 0
	intent_queue = 0
	left = 0
	member_time = 1
	members = 1
	query_queue = 0
	query_time = 1
serf_wan:
	coordinate_resets = 0
	encrypted = false
	event_queue = 0
	event_time = 1
	failed = 0
	health_score = 0
	intent_queue = 0
	left = 0
	member_time = 1
	members = 1
	query_queue = 0
	query_time = 1
default from the CLI embeded in the docker image `hashicorp/consul:1.22`
Server info
default from `docker pull hashicorp/consul:1.22`
default from `docker pull hashicorp/consul:1.22`

Operating system and Environment details

MacBook Pro M2 - MacOS 26.2

Log Fragments

No log. Just an error message. See above.

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