{"record":{"id":"78b872cee8431b5c","repo":"t8y2/dbx","slug":"etcd-v2-lease-unsupported","errorCode":"ETCD_V2_LEASE_UNSUPPORTED","errorMessage":"ETCD_V2_LEASE_UNSUPPORTED: the etcd v2 API has no lease objects; use ttl instead","messagePattern":"ETCD_V2_LEASE_UNSUPPORTED: the etcd v2 API has no lease objects; use ttl instead","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/etcd2-go/kv.go","lineNumber":203,"sourceCode":"\t\treturn nil, err\n\t}\n\tvalue, err := parseValueObject(rawObject(params, \"value\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\texpectedModRevision := longOrNull(params, \"expectedModRevision\")\n\texpectedCreateRevision := longOrNull(params, \"expectedCreateRevision\")\n\tttlValue := longOrNull(params, \"ttl\")\n\tpreserveLease := boolOrDefault(params, \"preserveLease\", false)\n\n\tleaseValue := longOrNull(params, \"lease\")\n\thasLease := leaseValue != nil\n\thasTtl := ttlValue != nil\n\tif (hasLease && hasTtl) || (preserveLease && (hasLease || hasTtl)) {\n\t\treturn nil, errors.New(\"lease, ttl, and preserveLease cannot be specified together\")\n\t}\n\tif hasLease {\n\t\treturn nil, errors.New(\"ETCD_V2_LEASE_UNSUPPORTED: the etcd v2 API has no lease objects; use ttl instead\")\n\t}\n\tif preserveLease {\n\t\treturn nil, errors.New(\"ETCD_V2_LEASE_UNSUPPORTED: the etcd v2 API has no lease objects; use ttl instead\")\n\t}\n\tif expectedCreateRevision != nil && *expectedCreateRevision != 0 {\n\t\treturn nil, errors.New(\"ETCD_V2_CAS_UNSUPPORTED: the etcd v2 API cannot compare createdIndex; use expectedModRevision\")\n\t}\n\tif hasTtl && *ttlValue <= 0 {\n\t\treturn nil, errors.New(\"ttl must be a positive integer\")\n\t}\n\n\tform := url.Values{}\n\tform.Set(\"value\", value)\n\tif hasTtl {\n\t\tform.Set(\"ttl\", strconv.FormatInt(*ttlValue, 10))\n\t}\n\tif expectedModRevision != nil {\n\t\tform.Set(\"prevIndex\", strconv.FormatInt(*expectedModRevision, 10))","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/etcd2-go/kv.go#L185-L221","documentation":"The etcd v2 API has no lease objects (those exist only in v3), so a put that specifies a lease can never be honored. After the mutual-exclusion check passes, a present lease value is rejected with this code. The message directs callers to use ttl instead, which v2 supports natively.","triggerScenarios":"Calling put with a non-nil 'lease' parameter (and not conflicting with ttl/preserveLease, which would fail earlier with the mutual-exclusion error).","commonSituations":"Reusing v3 client code that attaches lease IDs; a framework that always includes a lease field copied from cluster defaults; following v3 documentation while targeting a v2 endpoint.","solutions":["Remove the lease parameter and use ttl for expiry behavior","Migrate to the etcd v3 driver if lease semantics are required","Strip lease fields in a wrapper layer before calling v2 put"],"exampleFix":"// before\n{ \"key\":\"k\", \"value\":\"v\", \"lease\": 758784123 }\n// after\n{ \"key\":\"k\", \"value\":\"v\", \"ttl\": 60 }","handlingStrategy":"validation","validationCode":"if lease != nil {\n\treturn errors.New(\"etcd v2 does not support lease; use ttl\")\n}","typeGuard":null,"tryCatchPattern":"_, err := session.handle(ctx, \"put\", params)\nif err != nil && strings.Contains(err.Error(), \"ETCD_V2_LEASE_UNSUPPORTED\") {\n\tparams = dropLeaseAddTTL(params)\n\t_, err = session.handle(ctx, \"put\", params)\n}","preventionTips":["Never send lease fields to v2 sessions; centralize request building","Convert desired expiry to ttl seconds at the call site","If leases are required, target the v3 driver","Add a lint/test that v2 request payloads contain no 'lease' key"],"tags":["etcd","api-version","lease","unsupported"],"backgroundTag":"api-not-supported","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}