For AI agents: markdown of this page — /docs-content-en/infra/deploy/lock.md documentation index — /llms.txt

Release a stuck lock

DELETE /v1/infra/servers/:id/lock

Forcibly releases a stuck operation lock on the server. Use it when /exec or /deploy was aborted from the client side (lost connection, local timeout), but the lock is still active on the server and subsequent calls return EXEC_BUSY. The endpoint always returns 200: if a lock was held on this replica — it is released, the response carries released: true and localLock: true; if not — released: false (also a success).

The release is broadcast to all platform replicas (broadcast: true), so the endpoint releases a stuck lock even when it is held on a different replica — which is exactly why released can be false while the lock really was held and released on the holder replica. released/localLock describe only the current replica and are not proof of a fleet-wide release — do not poll the endpoint in a loop until released: true. Instead, retry the operation (/exec//deploy); if EXEC_BUSY persists, call /unstick, which is available for a dedicated virtual machine (kind: "STANDALONE") only. On a galaxy host and a Galaxy application the call returns 409 GALAXY_UNSTICK_UNSUPPORTED, because the exec channel is shared; there the remaining options are to retry at the Retry-After interval and, if the refusal persists, to contact support. The broadcast is best-effort (a no-op when only one replica is active, or if the bus is down); a guaranteed release of a stuck exec lock comes from the server-side TTL auto-sweep (below).

Use with care. Releasing the lock of an active operation can lead to an unpredictable server state — /exec and /deploy running at the same time may compete for files and systemd units.

Parameters

Parameter In Type Required Description
id path string (UUID) yes Server ID

The request body is empty.

Examples

curl — personal key

Terminal
curl -X DELETE -H "X-Api-Key: YOUR_API_KEY" \
  https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/lock

curl — OAuth application

Terminal
curl -X DELETE -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  https://vibecode.bitrix24.com/v1/infra/servers/SERVER_ID/lock

JavaScript — personal key

javascript
const res = await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/lock`,
  {
    method: 'DELETE',
    headers: { 'X-Api-Key': 'YOUR_API_KEY' },
  }
)
const { data } = await res.json()

if (data.released) {
  console.log(`Released lock ${data.operation}, held for ${data.ageMs}ms, ${data.expiresInMs}ms left before expiry`)
} else {
  // No local lock, but the release was broadcast to other replicas (data.broadcast === true).
  console.log(data.message)
}

JavaScript — OAuth application

javascript
await fetch(
  `https://vibecode.bitrix24.com/v1/infra/servers/${serverId}/lock`,
  {
    method: 'DELETE',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
    },
  }
)

Response fields

Field Type Description
success boolean Always true when called on an existing server
data.released boolean true — a lock was held on this replica and it was released. false — no local lock. Describes only the current replica, not the whole fleet
data.localLock boolean Whether the lock was held on this very replica (true when released: true)
data.broadcast boolean true — the release was broadcast to the other replicas. Delivery is requested but not confirmed, and the broadcast does nothing when only one replica is active or the bus is down
data.operation string Type of the released operation: "exec" or "deploy". Present only when released: true
data.ageMs number How many milliseconds the lock had been active. Present only when released: true
data.expiresInMs number In how many milliseconds the lock would have expired on its own. Present only when released: true
data.message string A note that there was no local lock and the release was broadcast to the replicas. Present only when released: false

Response example

A lock was held on this replica — released:

JSON
{
  "success": true,
  "data": {
    "released": true,
    "localLock": true,
    "broadcast": true,
    "operation": "deploy",
    "ageMs": 320000,
    "expiresInMs": 580000
  }
}

No local lock (the release was broadcast to other replicas):

JSON
{
  "success": true,
  "data": {
    "released": false,
    "localLock": false,
    "broadcast": true,
    "message": "No lock on this replica; a fleet-wide EXEC-lock release was broadcast to peers"
  }
}

Error response example

404 — server not found:

JSON
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Server not found"
  }
}

Errors

HTTP Code Description
401 MISSING_API_KEY The X-Api-Key header was not provided
401 INVALID_API_KEY Invalid or expired API key
403 INFRA_FORBIDDEN_FOR_COWORK_KEY The call was made with a Cowork/Code key — such a key works with data only and cannot perform write operations. To issue a key that can, see Project key for deploy
404 NOT_FOUND The server does not exist or belongs to another API key. Being on the server's development team does not grant access to this operation — it requires the managing key regardless of your role.
429 RATE_LIMITED The platform's overall request limit was exceeded

Full list of common API errors — Errors.

Known specifics

  • One lock per server. Protection against races between /exec and /deploy — they share one common lock. It is impossible to lock an individual command.
  • Auto-release on normal completion. /exec and /deploy release the lock themselves, whether they succeed or fail. DELETE /lock is only needed when the client aborted the connection before completion or the agent timed out without sending a final event.
  • Lock TTL — auto-expiry without a call. /exec sets the lock for timeout + 30 + 60 seconds. /deploy — for 15 minutes. Even without DELETE /lock, a stuck lock will expire on its own.
  • The release is broadcast to all replicas. The platform scales horizontally, and a stuck lock is held on the replica that took it, which is not necessarily the one serving your DELETE /lock. So the release is always broadcast fleet-wide (broadcast: true) — that is how the endpoint releases the lock on the holder replica. That is also why released can be false even when the lock really was released: the local replica did not hold it.
  • Guaranteed auto-release of a stuck exec lock. Even without DELETE /lock, a stuck exec lock is guaranteed to be released by a server-side background sweep shortly after its TTL expires (on the order of a few minutes) — for the case where the handler could not release it itself. DELETE /lock is the fast path; the sweep is the safety net. (There is no sweep for /deploy: a long deploy may legitimately exceed its TTL; a stuck deploy lock is released by DELETE /lock or by the operation finishing.)
  • released: false is a success, not an error. The endpoint does not return 404 when there is no lock, because the idea is to "guarantee there is no lock". The client does not care whether there was one or not.
  • Works in any server mode. Unlike most Deploy API endpoints, DELETE /lock does not require BLACKHOLE — the lock is held in the platform's memory and does not depend on the agent.
  • The lock outlives server deletion. A stuck lock survives its server: if the previous server was deleted but its in-memory lock remained, the next deploy fails with EXEC_BUSY. DELETE /lock releases such a lock even on a deleted server — as long as it still belongs to your API key (ownership is the only check; the lock itself holds no data and no cloud resources).

See also