Skip to main content

Troubleshooting: transfer target restricted

A transfer, warm (attended) transfer, park move, or dialer-scheduled step that comes back with 403 VOICE_TRANSFER_TARGET_RESTRICTED was blocked by the per-agent transfer policy — the routing/eligibility gate that decides which destinations an agent may hand a live call to. It is not the pre-flight destination gate chain, and it is not a trunk fault; the call never left the platform because policy said this agent may not send it there.

1. Symptom

Any of these transfer-like operations returns the 403 with VOICE_TRANSFER_TARGET_RESTRICTED:
  • a blind transfer (POST /voice/calls/:id/transfer)
  • a warm / attended transfer (consult-then-complete)
  • a park move or call-flip target
  • a dialer-scheduled transfer step
The caller stays on the line with the original agent; only the transfer leg was refused.

2. Where the gate fires

The gate runs at routing/eligibility time on the transfer target — before the destination is resolved to a queue, extension, SIP URI, or PSTN number, and before the call enters the agent queue. That is the distinction that settles most confusion:
  • The pre-send gate chain and the destination/emergency blocks page cover origination-time gates — they screen a new outbound call (emergency short codes, DNO caller-id, per-country rate window, trunk caller-id). Those fire on call-create, not on a mid-call move.
  • This page’s gate is the per-agent transfer-restriction policy — a governance control (sibling of the per-user dialing class-of-service) that says which kinds of destination an individual agent may transfer to, and optionally which specific extensions or queues. It lives in the org’s voice settings and is opt-in — until an admin sets enabled: true with agent entries or a default rule, nothing is restricted and this code cannot fire.
The reject also names its deciding entry in details.matched_by (the agent id that matched, or "default" for the org-wide default rule), so you can tell the policy gate from a routing misconfiguration from the error body alone.

3. Causes

Work these in order; each is a different control you own.
  1. Per-agent policy enforces a target-kind lockdown. The agent’s rule (or the org default rule) does not list the target’s kind — extension, queue, sip, or pstn. A policy set to “support queue and on-net extensions only” blocks every PSTN and SIP transfer with exactly this code.
  2. Fine-grained extension/queue whitelist misses the destination. The rule lists allowed_extensions or allowed_queues, and the target is not on it. An empty list is an explicit lockdown, not an “unrestricted” setting.
  3. Ambiguous queue selection. The transfer was aimed at a queue whose id does not appear in the agent’s allowed_queues whitelist — check the queue id the client resolved against the policy, not against the queue’s display name.
  4. The destination is genuinely non-routeable for this policy. The routes you want an agent to use must be written into the agent’s rule (or into the org default); a rule that names queue as a kind but a whitelist that omits the queue blocks the transfer.
  5. A 403 on the same code was mistaken for a routing misconfiguration. If details.matched_by is present, the policy gate fired — do not rework trunk or queue config. A missing matched_by means the policy lookup itself failed-open (allow), so a 403 from that request is a different layer — fall back to the destination-blocks decision matrix.

4. Fix

  • If the block is intentional (the policy says this agent should not reach that destination): no fix — the gate is doing what it was configured to do. Tell the agent the destination is restricted, or record it as a deliberate lockdown.
  • If the block is mis-scoped: an org owner/admin adjusts the org’s voice transfer-restriction settings — update the agent’s entry (or the default_rule) to add the missing target kind, or to add the specific extension digits / queue id to its whitelist. The change takes effect on the next transfer attempt; no campaign or dialer re-launch is needed.
  • If the destination should never have been targeted: treat this as you would a destination block — retarget the transfer to a destination the policy names. Emergency short codes are never governed by this policy (the unconditional emergency-call guard owns them), so an emergency-class target is not a candidate here.

5. See also