Understand admission errors

Symptom

Your client receives an error from ‹source›.swarmvia.cloud (or your custom domain) with a swarmvia error body, often before any upstream latency.

Common statuses

401 unauthorized

The caller's credential was missing or rejected: an access key, a JWT, or a Cloudflare Access token. Auth failures never take a concurrency slot. The message field says which check failed:

message What it means What to do
missing access key The source requires a key and none was sent. Send the key in X-Swarmvia-Key.
legacy access key no longer accepted The key starts with nb_live_. Those older keys stopped working on November 7, 2026. Mint an access token instead. For an integration, use a Control API token; see Refresh access tokens before they expire.
invalid access token The key is not a valid access key: it does not start with sv_at_, it is malformed, its signature does not verify, or it was issued for a different source. Send the key exactly as it was returned, to the source it was minted for. If it still fails, mint a new one.
access token expired The key is past its expires_at. Mint a new key: agents start a new session with start_source_session (up to 7d with expires_in); integrations call the Control API again. Refresh before expiry to avoid this (how).
access token revoked The key was revoked with revoke_source_session, the Control API, or on the Access tab, or the member it acts for left the organization. Mint a new key. If you did not revoke it, ask the source's owner why it was revoked.
{
  "error": "unauthorized",
  "message": "access token expired"
}

JWT and Cloudflare Access failures carry their own messages. Check the issuer, audience, and token expiry against the source's Access settings.

403

IP policy rejection (a blocked range, or outside the allowed ranges), or the source's custom-hostname lock is on and you called the canonical *.swarmvia.cloud host.

400

Origin selection failed. Send a valid X-Swarmvia-Origin that exactly matches a configured origin, or ensure the path matches a configured path prefix.

413 payload_too_large

The body exceeds a size limit for bodies that must be fully read. With origin verification on and no usable Content-Length, swarmvia cannot bind the length of a streamed body over 10 MB. With a correct Content-Length, origin verification signs the first 1 MB and streams the rest (no size-based 413).

Shrink the payload, or send Content-Length on large origin-verified uploads.

429 too_many_requests

The request never entered an open wait: the source queue is already full, the caller set X-Swarmvia-No-Queue, or the RPM gate is overloaded. Honor Retry-After when present. Raise queue depth / concurrency only within plan limits, or shed load at the client.

504 queue_timeout

The open wait ran out before a slot freed. Body message: Source queue timeout: no slot available within the wait budget. Raise queue timeout, raise concurrency, or lower load.

504 request_timeout

The request held a slot past the request timeout. Body message: Source request timeout: exceeded the slot lease. Raise it if the upstream call is slow, or fix hung upstream work. A response whose headers already arrived cannot turn into a 504: if its body is still streaming at the request timeout, the body is cut off instead. Both timeout responses include x-swarmvia-* governor headers (total-ms, slot/queue stats) so you can tell them apart from a Cloudflare HTML 524.

424 credential_needs_reauthorization

The source's OAuth 2.0 credential was rejected by its token endpoint. The reason field carries the provider's code, for example invalid_grant for a revoked refresh token. Retrying will not help. Open reconnect_url and rotate the credential. See Credential health.

{
  "error": "credential_needs_reauthorization",
  "message": "The upstream token endpoint rejected this source's credential (invalid_grant). Reconnect or rotate it in the dashboard.",
  "reason": "invalid_grant",
  "reconnect_url": "https://swarmvia.com/sources/orders-acme/reconnect"
}

403 credential_requires_member_key

The source uses a per-member credential: each call is made with the connected account of the member the key acts for. This key is a machine key. Mint one with Acts for: Me, or connect the agent over MCP so its session keys act for you.

424 credential_missing

A managed source has no credential attached. Attach one on the source's Access tab.

503 credential_unavailable

The token endpoint for the source's OAuth 2.0 credential is failing (5xx, throttled, or unreachable), or, with reason: vault_error, swarmvia briefly could not read the stored credential. Honor Retry-After; swarmvia backs off and recovers on its own. The origin was not called.

MCP sources

An MCP source answers GET /tools and POST /tools/call and nothing else. Its own errors:

Status and error What it means
403 tool_not_allowed The source's tool list does not include this tool. GET /tools shows the ones it does. The server was not called.
403 tool_not_read_only The key is read-only, and the server does not mark this tool as read-only. A connector calls every tool checked on the source page, read or write. Reconnecting the connector does not change that list.
400 invalid_tool_call The server refused the call itself: an unknown tool or arguments that do not match its schema. code carries the server's JSON-RPC code.
424 credential_needs_reauthorization with reason: upstream_rejected_token The server refused the token swarmvia sent. Reconnect (OAuth) or rotate the stored token.
424 credential_insufficient_scope The server needs more access than the connection granted. required_scope names it; reconnect to grant it.
424 credential_missing with reason: upstream_requires_auth The server needed no authorization when the source was created and now does. Connect a credential.
429 upstream_throttled The server is rate-limiting. Honor Retry-After.
502 mcp_error / mcp_protocol_error The server failed the request, or answered in a way that is not valid MCP.

A tool that ran and failed is not an error at this level: the call returns 200 with result.isError: true, the same as the server sent it.

503 pool_suspended

Body message: This source is suspended. Billing or policy suspension. Check Billing and source status in the dashboard.

501 pool_not_configured

Body message: This source has no upstream routing configured yet. The source is not configured yet. Re-save the source in the dashboard or wait a moment after create.

What to check

  1. Source Access settings vs the headers you send
  2. Concurrency / RPM settings and current live status on the source page
  3. Access Logs for the reject reason and timing fields
  4. Whether you intended proxy vs lock API

See also