t8y2/dbx · error
ETCD_V2_UNSUPPORTED
ETCD_V2_UNSUPPORTED
Error message
ETCD_V2_UNSUPPORTED: %s is not available on the etcd v2 API
What it means
The v2 runtime's handle() dispatch checks isEtcd3OnlyMethod and rejects methods that exist only in etcd's v3 API (e.g. kv_history, etcd_compact, etcd_defrag, watches, leases) with this coded error. The v2 driver cannot emulate those primitives, so it fails explicitly instead of silently misbehaving.
Source
Thrown at agents/drivers/etcd2-go/main.go:388
case "etcd_auth_role_get":
return s.authRoleGet(params)
case "etcd_auth_role_add":
return s.authRoleAdd(params)
case "etcd_auth_role_delete":
return s.authRoleDelete(params)
case "etcd_auth_role_grant_permission":
return s.authRolePermission(params, true)
case "etcd_auth_role_revoke_permission":
return s.authRolePermission(params, false)
case "disconnect":
s.close()
return map[string]bool{"ok": true}, nil
case "shutdown":
s.close()
return map[string]bool{"ok": true}, nil
default:
if isEtcd3OnlyMethod(method) {
return nil, fmt.Errorf("ETCD_V2_UNSUPPORTED: %s is not available on the etcd v2 API", method)
}
return nil, fmt.Errorf("unknown method: %s", method)
}
}
func isEtcd3OnlyMethod(method string) bool {
switch method {
case "kv_history", "etcd_compact", "etcd_defrag",
"etcd_lease_list", "etcd_lease_get", "etcd_lease_grant",
"etcd_lease_keepalive_once", "etcd_lease_revoke":
return true
}
return false
}
func decodeParams(params map[string]json.RawMessage, target any) error {
if params == nil {
params = map[string]json.RawMessage{}View on GitHub (pinned to c0390bff16)
Solutions
- Use the etcd3 (gRPC) driver for methods requiring v3 semantics.
- Gate the call behind a capability check (isEtcd3OnlyMethod or equivalent) before dispatch.
- Rework the operation using v2 primitives where possible (e.g. poll keys instead of watch).
Example fix
// before
handle(v2Session, "etcd_defrag", {})
// after
if !isEtcd3OnlyMethod("etcd_defrag") { handle(v2Session, "etcd_defrag", {}) } // or use the v3 driver Defensive patterns
Strategy: validation
Validate before calling
if isEtcd3OnlyMethod(method) { return fmt.Errorf("method %s requires the etcd3 driver; v2 driver in use", method) } Type guard
func v2Capable(method string) bool { return !isEtcd3OnlyMethod(method) } Try / catch
if err := handle(session, method, params); err != nil && strings.Contains(err.Error(), "ETCD_V2_UNSUPPORTED") {
return routeToV3Driver(session, method, params)
} Prevention
- Feature-detect the driver (v2 vs v3) before dispatch
- Centralize method routing in one place that knows v2 limitations
- Read isEtcd3OnlyMethod's list when adding new callers
When it happens
Trigger: Sending an etcd3-only method name (per isEtcd3OnlyMethod's switch list) to the etcd2 driver's handle(), e.g. calling etcd_compact or kv_history through the v2 agent.
Common situations: Shared client code written against an etcd3 driver pointed at the v2 driver, feature-detection missing, tests like TestEtcd3OnlyMethodsRejected exercising the rejection path.
Related errors
- user is required
- Not connected
- Client certificate and key must be provided together
- No etcd endpoint configured
- ETCD_COMPACTED
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/620475137e89e3f0.
Report an issue: GitHub.