Consul 1.21.5 breaks existing keyvault entries with illegal key name
- Dominant language
- Go
- Stars
- 30.1k
- Forks
- 4.6k
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 39
Description
#### 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"
```
Contributor guide
Research direction
Start with the Consul KV get, export, and import paths described in the reproduction, then compare the behavior introduced by PR 22682. Reproduce the percent-encoded key failure across the 1.21.5 upgrade; done means existing keys such as foo/bar/baz%2Fqux remain usable and kv import works.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100