consul icon indicating copy to clipboard operation
consul copied to clipboard

Consul 1.21.5 breaks existing keyvault entries with illegal key name

Open lerlacher-fm opened this issue 5 months ago • 10 comments

Overview of the Issue

https://github.com/hashicorp/consul/pull/22682 is a major breaking change but was released in a patch release.

It silently breaks kv operations for existing kv entries with a (now) illegal key name.

This is going to impact anyone who has used uuencode / url encode / percent-encoding to mask the / character in their consul keys as part of their hierarchical organization of their consul kv, which I expect to be many people.


Reproduction Steps

  • Have an existing consul cluster with version < 1.21.5 with key names such as (from consul kv export):
[
        {
                "key": "foo/bar/baz%2Fqux",
                "flags": 0,
                "value": "XXXXXXX"
        }
]
  • Observe that consul kv get 'foo/bar/baz%2Fqux' works
  • Upgrade consul to 1.21.5
  • Observe that consul kv get 'foo/bar/baz%2Fqux' no longer works

consul kv export still works, but consul kv import does not.

Consul info for both Client and Server

[root ~] [1] # consul info
agent:
	check_monitors = 0
	check_ttls = 0
	checks = 2
	services = 40
build:
	prerelease = 
	revision = 3261d11a
	version = 1.21.5
	version_metadata = 
consul:
	acl = disabled
	bootstrap = true
	known_datacenters = 1
	leader = true
	leader_addr = 10.37.129.192:8300
	server = true
raft:
	applied_index = 182221
	commit_index = 182221
	fsm_pending = 0
	last_contact = 0
	last_log_index = 182221
	last_log_term = 4
	last_snapshot_index = 180239
	last_snapshot_term = 3
	latest_configuration = [{Suffrage:Voter ID:8206222e-a5c1-185e-0e54-a6039138008e Address:10.37.129.192: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 = 4
runtime:
	arch = amd64
	cpu_count = 4
	goroutines = 352
	max_procs = 2
	os = linux
	version = go1.25.0
serf_lan:
	coordinate_resets = 0
	encrypted = false
	event_queue = 1
	event_time = 301
	failed = 0
	health_score = 0
	intent_queue = 1
	left = 0
	member_time = 6
	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 = 3
	members = 1
	query_queue = 0
	query_time = 1

Operating system and Environment details

Debian

Log Fragments

2025-09-24T02:46:34.700732-04:00 some-server-hostname consul[2573172]: agent.http: Request error: method=GET url="/v1/kv/foo/bar/baz%252Fqux?stale=1" from=127.0.0.1:45122 error="invalid key name, keys should respect the \"^[a-zA-Z0-9,_./\\-?&=]+$\" format"

lerlacher-fm avatar Sep 24 '25 07:09 lerlacher-fm

Hi,

this change breaks existing Terraform states stored in Consul. After upgrading Consul to 1.21.5, terraform init fails with:

# terraform init
Initializing the backend...
Initializing modules...
╷
│ Error: Failed to get existing workspaces: Unexpected response code: 500 (invalid key name, keys should respect the "^[a-zA-Z0-9,_./\\-?&=]+$" format)
│
│
╵

Environment:

terraform --version
Terraform v1.13.3
on darwin_arm64
+ provider registry.terraform.io/hashicorp/vault v5.1.0
+ provider registry.terraform.io/tchupp/env v0.0.2
+ provider registry.terraform.io/terraform-provider-openstack/openstack v3.3.2

Cheers, Marius

mxhash avatar Sep 24 '25 11:09 mxhash

It also breaks Vault Consul storage:

/v1/kv/vault/core/plugin-catalog/database/kv/v0.24.0+builtin contains the + symbol, which isn't allowed by the regex.

AlexeyDemidov avatar Sep 26 '25 13:09 AlexeyDemidov

It looks like this new check can be disabled via disable_http_unprintable_char_filter.

Have you tried setting this to true in your agent config?

dcarbone avatar Sep 26 '25 13:09 dcarbone

Hey folks, sorry to hear that this change broke some integrations. It was a sanitization we've added to prevent potential path traversals in our key names in the kv endpoint following an external security assessment. The disable_http_unprintable_char_filter should indeed disable it and feel free to use it if your key names are well sanitized. We'll adjust the kv regex in the next Consul version to include + , *, ? and %. Please feel free to @ me here if you have another character that causes an issue and isn't capturer in here. Thanks a lot for reporting this, we'll get a fix as soon as possible.

dduzgun-security avatar Sep 26 '25 15:09 dduzgun-security

@dduzgun-security Are those extra characters going to be enough to fix the issues with Traefik, which uses a hard-coded key with the ç character in as part of their healthchecks?

Also, it would probably be worth updating the documentation which currently says "Keys, like objects, are not restricted by type and can include any character", as that's no longer correct.

uduncanu avatar Sep 29 '25 13:09 uduncanu

@uduncanu Good catch, I suggested it in the PR: https://github.com/hashicorp/consul/pull/22850

dduzgun-security avatar Sep 29 '25 15:09 dduzgun-security

Hi @dduzgun-security,

I want to suggest also the colon ":" character which is used in consul esm!

Consul ESM is writing its key always with the keyname with "${CONSUL_SERVICE_NAME}:${CONSUL_INSTANCE_ID}"!

JHPUR287 avatar Sep 30 '25 14:09 JHPUR287

Not sure if anyone else would like to chime in on the PR improving this KV validation feature

https://github.com/hashicorp/consul/pull/22863

ghthor avatar Oct 03 '25 20:10 ghthor

I'm seeing the same issue with Orleans and Consul as membership provider. Keys are of the form orleans/Staging/192.168.147.66:11111@122992601 (note the : and @)

ahilsend avatar Nov 24 '25 13:11 ahilsend

@ahilsend do you have the same behaviour on Consul 1.22?

dduzgun-security avatar Nov 24 '25 15:11 dduzgun-security