caddyserver/caddy · error
depleted attempts to find an available config_id
Error message
depleted attempts to find an available config_id
What it means
ECH config IDs are a single byte (0-255). newECHConfigID does rejection sampling: up to 256 random draws, skipping IDs whose ech/configs/<id> path already Exists in storage. If every distinct ID was either tried-and-taken (or context cancelled, which is returned separately), allocation gives up with this error. In practice it means storage holds entries for (nearly) all 256 IDs — usually accumulated stale/orphaned configs from rotations or partial writes.
Source
Thrown at modules/caddytls/ech.go:1143
continue
}
tried[num] = true
// check to see if any of the subkeys use this config ID
numStr := strconv.Itoa(int(num))
trialPath := path.Join(echConfigsKey, numStr)
if ctx.Storage().Exists(ctx, trialPath) {
continue
}
return num, nil
}
if err := ctx.Err(); err != nil {
return 0, err
}
return 0, fmt.Errorf("depleted attempts to find an available config_id")
}
// ECHPublisher is an interface for publishing ECHConfigList values
// so that they can be used by clients.
type ECHPublisher interface {
// Returns a key that is unique to this publisher and its configuration.
// A publisher's ID combined with its config is a valid key.
// It is used to prevent duplicating publications.
PublisherKey() string
// Publishes the ECH config list (as binary) for the given innerNames. Some
// publishers may not need a list of inner/protected names, and can ignore the
// argument; most, however, will want to use it to know which inner names are
// to be associated with the given ECH config list.
//
// Implementations should return an error of type PublishECHConfigListErrors
// when relevant to key errors to their associated innerName, but should never
// return a non-nil PublishECHConfigListErrors when its length is 0.View on GitHub (pinned to 50e54ee279)
Solutions
- List ech/configs/ in storage and delete stale entries (those with old Created timestamps in meta.json, or directories missing config.bin/meta.json).
- If rotation naturally fills the space, prune expired ECH configs as part of maintenance.
- Verify no process is repeatedly creating partial ECH configs (check for the per-write store errors) and fix that root cause.
- Restart Caddy after cleanup so provisioning retries ID allocation.
Example fix
# before: all 256 IDs occupied
$ ls ~/.local/share/caddy/ech/configs | wc -l
256
# after: remove stale/partial entries (keep recent ones)
$ find ~/.local/share/caddy/ech/configs -name meta.json -mtime +30 \
-exec dirname {} \; | xargs rm -rf Defensive patterns
Strategy: validation
Validate before calling
// Maintenance check: count occupied ECH config IDs and prune stale ones.
func echIDUsage(ctx context.Context, stor caddy.Storage) (int, error) {
entries, err := stor.List(ctx, "ech/configs", false)
if err != nil {
return 0, err
}
return len(entries), nil
} Try / catch
if err != nil && strings.Contains(err.Error(), "depleted attempts to find an available config_id") {
// storage has (nearly) all 256 IDs taken: prune ech/configs/* and restart
} Prevention
- Periodically delete old ECH configs (rotation accumulates entries; ID space is 256).
- Clean partial ech/configs/<id> dirs missing config.bin or meta.json after storage incidents.
- Alert when occupied ECH IDs exceed ~200 so cleanup happens before exhaustion.
When it happens
Trigger: The ech/configs/ prefix in storage contains subdirectories for all 256 possible numeric IDs — e.g. after many ECH rotations without cleanup, or repeated failed provisioning runs that each stranded partial entries (key.bin written but later step failed).
Common situations: Long-running Caddy with ECH on and rotation creating new configs each interval; storage littered by crash-looping during provisioning; copying a cluttered storage between environments.
Related errors
- --output is required
- cannot reuse socket %v: unix socket is already in use by ano
- generating unique config ID: %v
- storing ECH private key: %v
- storing ECH config: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/8e89e382f221495c.
Report an issue: GitHub.