---
title: Error Reference
description: Every well-known error code the Cetacean API returns, with its HTTP
  status, what it means, and how to resolve it.
canonical: https://cetacean.mazetti.me/api/errors
---

# Error Reference

A domain-specific error carries a stable code as the last path segment of the `type` field in its [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) problem document — `"type": "/api/errors/SVC001"` is the entry below. Generic HTTP errors use `about:blank` and have no code.

A running Cetacean serves the same catalog at `GET /api/errors`, and one entry at `GET /api/errors/{code}`. This page is generated from the same source, so the two cannot disagree.

## API: Protocol and content negotiation

### `API001` — SSE Not Supported

**Status** — 406

This endpoint does not support Server-Sent Events.

**Resolution** — Use Accept: application/json instead of text/event-stream.

### `API002` — SSE Required

**Status** — 406

This endpoint only supports Server-Sent Events.

**Resolution** — Use Accept: text/event-stream.

### `API003` — Not Acceptable

**Status** — 406

The Accept header does not match any media type this endpoint can produce.

**Resolution** — Use Accept: application/json, application/atom+xml, text/event-stream, or text/html.

### `API004` — Invalid Patch Content-Type

**Status** — 415

The Content-Type header does not match a supported patch format.

**Resolution** — Use Content-Type: application/merge-patch+json or application/json-patch+json.

### `API005` — Streaming Not Supported

**Status** — 500

The server's response writer does not support streaming (no http.Flusher).

**Resolution** — This is a server configuration issue. Check that no middleware is buffering responses.

### `API006` — Invalid Request Body

**Status** — 400

The request body could not be decoded as valid JSON.

**Resolution** — Ensure the request body is well-formed JSON matching the expected schema.

### `API007` — Unreadable Request Body

**Status** — 400

The request body could not be read.

**Resolution** — Ensure the request includes a body and Content-Length is correct.

### `API008` — Invalid JSON

**Status** — 400

The request body is not valid JSON.

**Resolution** — Check for syntax errors in the JSON payload.

### `API009` — Internal Serialization Error

**Status** — 500

The server failed to serialize or deserialize internal state.

**Resolution** — This is a server bug. Check the Cetacean logs for details.

### `API010` — Patch Test Failed

**Status** — 409

A JSON Patch test operation failed, indicating the resource state does not match the expected value.

**Resolution** — Reload the resource and retry the patch with updated test values.

### `API011` — Patch Application Failed

**Status** — 400

The JSON Patch could not be applied to the resource.

**Resolution** — Check the patch operations for correctness.

### `API012` — Endpoint Removed

**Status** — 410

This endpoint was deprecated and has since been removed.

**Resolution** — See the endpoint named in the detail, or GET /api for the current surface.

### `API013` — Precondition Failed

**Status** — 412

The If-Match header did not match the current state of the resource.

**Resolution** — Re-read the resource, take the ETag from that response, and retry with it.

### `API014` — Not Representable as Compose

**Status** — 422

The resource has nothing a compose file can describe. A service running a plugin or a network attachment has no container specification, which is all a compose service is.

**Resolution** — Read the resource as JSON instead; only container services have a compose projection.

### `API015` — Ambiguous Identifier

**Status** — 409

The name in the path or request body identifies more than one resource, so the server cannot tell which one was meant. Swarm does not require node hostnames to be unique.

**Resolution** — Address the resource by its ID. The detail names every ID the request could have meant.

## AUT: Authentication

### `AUT001` — Not Authenticated

**Status** — 401

The request requires authentication but no valid credentials were provided.

**Resolution** — Log in or provide a valid authentication token.

### `AUT002` — Authorization Denied

**Status** — 403

The identity provider denied authorization.

**Resolution** — Check your account permissions with the identity provider.

### `AUT003` — Authentication Callback Error

**Status** — 400

The authentication callback contained invalid or missing parameters.

**Resolution** — Retry the login flow from the beginning.

### `AUT004` — Authentication Server Error

**Status** — 500

An internal error occurred during authentication.

**Resolution** — Retry the login flow. If the problem persists, check server logs.

### `AUT005` — Client Certificate Rejected

**Status** — 403

The client certificate was absent, unreadable, or carried no usable identity.

**Resolution** — Present a certificate from a CA this deployment trusts, carrying a common name, email address or SPIFFE URI SAN.

### `AUT006` — Authentication Refused

**Status** — 403

The credential this deployment authenticates with was missing or rejected, and no HTTP authentication scheme can ask for it.

**Resolution** — The credential comes from the network path — a trusted proxy's headers, or the peer's tailnet membership — not from the request. Check the server logs for which one failed.

## ACL: Authorization

### `ACL001` — Access Denied

**Status** — 403

You do not have permission to access this resource.

**Resolution** — Check your ACL policy grants.

### `ACL002` — Write Access Denied

**Status** — 403

You do not have write permission on this resource.

**Resolution** — Check your ACL policy grants for write permissions.

## OPS: Operations level

### `OPS001` — Operations Level Too Low

**Status** — 403

The requested operation requires a higher operations level than the server is configured for.

**Resolution** — Increase the server.operations_level setting and restart the server.

## CSR: Cross-origin protection

### `CSR001` — Cross-Origin Request Blocked

**Status** — 403

The request changes state and arrived from another origin, which cross-site request forgery protection refuses.

**Resolution** — Call the API from an allowed origin, or add yours to the server.cors.origins setting.

## FLT: Filter expressions

### `FLT001` — Filter Expression Too Long

**Status** — 400

The filter expression exceeds the maximum allowed length.

**Resolution** — Shorten the filter expression.

### `FLT002` — Invalid Filter Expression

**Status** — 400

The filter expression could not be compiled, names a field the resource does not have, or compares values of different types.

**Resolution** — Check the expression syntax and the filter fields documented for this resource type. Filters use the expr-lang expression language.

### `FLT003` — Filter Evaluation Error

**Status** — 400

The filter expression compiled but failed during evaluation.

**Resolution** — Check the values the expression passes to each operator and function.

### `FLT004` — Filter Too Expensive

**Status** — 400

The filter expression was too expensive to evaluate over the list.

**Resolution** — Compare fields of the resource instead of building large collections in the expression.

## SEA: Search

### `SEA001` — Missing Search Query

**Status** — 400

The required query parameter q is missing.

**Resolution** — Provide a search query: /search?q=term.

### `SEA002` — Search Query Too Long

**Status** — 400

The search query exceeds the maximum allowed length of 200 characters.

**Resolution** — Shorten the search query.

## MTR: Metrics and Prometheus

### `MTR001` — Prometheus Not Configured

**Status** — 503

Prometheus metrics are not available because no Prometheus URL is configured.

**Resolution** — Set the prometheus.url setting and restart the server.

### `MTR002` — Prometheus Unreachable

**Status** — 502

The configured Prometheus server is not responding.

**Resolution** — Check that Prometheus is running and reachable at the configured URL.

### `MTR003` — Missing Metrics Query

**Status** — 400

The required query parameter is missing for the metrics endpoint.

**Resolution** — Provide a PromQL query parameter.

### `MTR004` — Invalid Metrics Step

**Status** — 400

The step parameter is outside the allowed range.

**Resolution** — Use a step value between 5 and 300 seconds.

### `MTR005` — Too Many Metrics Streams

**Status** — 429

The maximum number of concurrent metrics stream connections has been reached.

**Resolution** — Close an existing metrics stream connection before opening a new one.

### `MTR006` — Missing Label Name

**Status** — 400

The label name path parameter is missing.

**Resolution** — Provide a label name in the URL path.

### `MTR007` — Prometheus Request Failed

**Status** — 500

Failed to create the request to the Prometheus server.

**Resolution** — This is a server-side error. Check the Cetacean logs for details.

## LOG: Log streaming

### `LOG001` — Too Many Log Streams

**Status** — 429

The maximum number of concurrent log stream connections has been reached.

**Resolution** — Close an existing log stream before opening a new one.

### `LOG002` — Invalid Stream Parameter

**Status** — 400

The stream parameter must be either stdout or stderr.

**Resolution** — Use stream=stdout or stream=stderr.

### `LOG003` — Invalid After Parameter

**Status** — 400

The after parameter must be an RFC 3339 timestamp or a Go duration string.

**Resolution** — Use a format like 2024-01-01T00:00:00Z or 1h30m.

### `LOG004` — Invalid Before Parameter

**Status** — 400

The before parameter must be an RFC 3339 timestamp or a Go duration string.

**Resolution** — Use a format like 2024-01-01T00:00:00Z or 1h30m.

### `LOG005` — Before Not Supported For SSE

**Status** — 400

The before parameter is not supported for SSE log streams because they are open-ended.

**Resolution** — Remove the before parameter when using SSE, or use a JSON request instead.

### `LOG006` — Log Retrieval Failed

**Status** — 500

Failed to retrieve logs from the Docker Engine.

**Resolution** — Check that the service or task still exists and the Docker Engine is reachable.

### `LOG007` — Log Parse Failed

**Status** — 500

The logs were retrieved but could not be parsed.

**Resolution** — This is a server-side error. Check the Cetacean logs for details.

### `LOG008` — Log Stream Failed

**Status** — 500

Failed to open the log stream from the Docker Engine.

**Resolution** — Check that the service or task still exists and the Docker Engine is reachable.

### `LOG009` — Too Many Log Reads

**Status** — 429

The maximum number of concurrent log reads has been reached.

**Resolution** — Retry after the time the Retry-After header names.

## SSE: SSE connections

### `SSE001` — Too Many SSE Connections

**Status** — 429

The maximum number of concurrent SSE connections has been reached, for the server or for this caller.

**Resolution** — Close an existing SSE connection before opening a new one.

## ENG: Docker Engine

### `ENG001` — Docker Engine Unavailable

**Status** — 503

The Docker Engine is not responding. The daemon may be stopped, restarting, or the socket may be unreachable.

**Resolution** — Check that the Docker daemon is running and that Cetacean has access to the Docker socket.

### `ENG002` — Docker Version Check Failed

**Status** — 503

Could not determine the latest Docker Engine version from the GitHub API.

**Resolution** — This is a transient network error. Try again later.

### `ENG003` — Docker Validation Error

**Status** — 400

The Docker Engine rejected the request due to invalid arguments.

**Resolution** — Check the request parameters for correctness.

### `ENG004` — Docker Engine Error

**Status** — 500

An unexpected error occurred while communicating with the Docker Engine.

**Resolution** — Check the Cetacean and Docker daemon logs for details.

### `ENG005` — Docker Engine Timeout

**Status** — 504

The Docker Engine did not answer within the time Cetacean allows for the operation.

**Resolution** — Check the daemon's load and logs, then retry.

### `ENG006` — Cluster Re-sync Failed

**Status** — 502

Cetacean could not read the cluster from the Docker Engine. The detail names what each list answered.

**Resolution** — Check that docker.host points at a swarm manager and that the swarm has a leader.

## SWM: Swarm operations

### `SWM001` — Swarm API Not Available

**Status** — 501

The swarm API is not available. This node may not be a swarm manager, or the Docker Engine may not support swarm mode.

**Resolution** — Ensure Cetacean is connected to a swarm manager node.

### `SWM002` — Swarm Inspect Failed

**Status** — 503

Failed to inspect the current swarm state. The swarm may be temporarily unavailable.

**Resolution** — Check that the swarm is healthy and retry the operation.

### `SWM003` — Swarm Update Failed

**Status** — 500

The swarm configuration update failed.

**Resolution** — Check the Cetacean and Docker daemon logs for details.

### `SWM004` — Disk Usage Not Available

**Status** — 501

Disk usage information is not available from the Docker Engine.

**Resolution** — Ensure Cetacean is connected to a Docker Engine that supports the disk usage API.

### `SWM005` — Disk Usage Failed

**Status** — 500

Failed to retrieve disk usage information from the Docker Engine.

**Resolution** — Check the Docker daemon logs for details.

### `SWM006` — Token Rotation Failed

**Status** — 500

Failed to rotate the swarm join token.

**Resolution** — Check the Docker daemon logs for details.

### `SWM007` — Unlock Key Rotation Failed

**Status** — 500

Failed to rotate the swarm unlock key.

**Resolution** — Check the Docker daemon logs for details.

### `SWM008` — Swarm Unlock Failed

**Status** — 500

Failed to unlock the swarm with the provided key.

**Resolution** — Verify the unlock key is correct and try again.

### `SWM009` — Unlock Key Retrieval Failed

**Status** — 500

Failed to retrieve the swarm unlock key.

**Resolution** — Check the Docker daemon logs for details.

### `SWM010` — Unlock Key Required

**Status** — 400

The unlock key is required to unlock the swarm.

**Resolution** — Provide the unlockKey field in the request body.

### `SWM011` — Invalid Token Target

**Status** — 400

The token rotation target must be either worker or manager.

**Resolution** — Use target=worker or target=manager.

## PLG: Plugin operations

### `PLG001` — Plugin List Failed

**Status** — 500

Failed to list plugins from the Docker Engine.

**Resolution** — Check that the Docker daemon is running and reachable.

### `PLG002` — Plugin Remote Required

**Status** — 400

The remote field is required for plugin operations.

**Resolution** — Provide the remote field specifying the plugin image reference.

### `PLG003` — Plugin Privilege Check Failed

**Status** — 500

Failed to check the required privileges for the plugin.

**Resolution** — Check the Docker daemon logs for details.

### `PLG004` — Plugin Not Found

**Status** — 404

The requested plugin does not exist on this Docker host.

**Resolution** — Check the plugin name and verify it is installed.

### `PLG005` — Plugin Privileges Required

**Status** — 400

An install or upgrade must name the privileges it grants.

**Resolution** — Send the privileges POST /plugins/privileges returned for this remote.

### `PLG006` — Plugin Privileges Changed

**Status** — 409

The plugin now requires different privileges from the ones the request grants.

**Resolution** — Check the privileges again with POST /plugins/privileges and review the new set.

## NOD: Node operations

### `NOD001` — Node Not Down

**Status** — 409

The node cannot be removed in its current state. A node must be down before it can be removed from the swarm, and a manager must first be demoted to worker.

**Resolution** — Demote the node if it is a manager. Then have the node leave the swarm or stop it so it goes down, or use force removal to remove a worker immediately. Draining a node does not take it down.

### `NOD002` — Node Version Conflict

**Status** — 409

The node was modified by another client between the time it was read and the time the update was submitted.

**Resolution** — Reload the node and retry the operation.

### `NOD003` — Node Not Found

**Status** — 404

The specified node does not exist in the swarm.

**Resolution** — Check the node ID or hostname and try again.

### `NOD004` — Invalid Availability Value

**Status** — 400

The availability value must be one of: active, drain, pause.

**Resolution** — Use availability=active, availability=drain, or availability=pause.

### `NOD005` — Invalid Role Value

**Status** — 400

The role value must be one of: worker, manager.

**Resolution** — Use role=worker or role=manager.

## SVC: Service operations

### `SVC001` — Service Version Conflict

**Status** — 409

The service was modified by another client between the time it was read and the time the update was submitted.

**Resolution** — Reload the service and retry the operation.

### `SVC002` — Service In Use

**Status** — 409

The service cannot be removed because it is still referenced by other resources or managed by a stack.

**Resolution** — Remove the stack that manages this service, or detach the service from the stack first.

### `SVC003` — Service Not Found

**Status** — 404

The specified service does not exist in the swarm.

**Resolution** — Check the service ID or name and try again.

### `SVC004` — Replicas Required

**Status** — 400

The replicas field is required for this operation.

**Resolution** — Provide the replicas field in the request body.

### `SVC005` — Cannot Scale Global Service

**Status** — 400

Global-mode services run exactly one task per node and cannot be scaled manually.

**Resolution** — To change the number of tasks, switch the service to replicated mode first.

### `SVC006` — Image Required

**Status** — 400

The image field is required for service image updates.

**Resolution** — Provide the image field in the request body.

### `SVC007` — No Previous Spec

**Status** — 400

The service has no previous specification to rollback to.

**Resolution** — Rollback is only available after at least one update has been applied to the service.

### `SVC010` — Invalid Endpoint Mode

**Status** — 400

The endpoint mode must be one of: vip, dnsrr.

**Resolution** — Use mode=vip or mode=dnsrr.

### `SVC011` — Invalid Resource Specification

**Status** — 400

The merged resource specification is not valid.

**Resolution** — Check the resource limits and reservations in the request body.

### `SVC012` — Invalid Update Policy

**Status** — 400

The merged update policy specification is not valid.

**Resolution** — Check the update policy fields in the request body.

### `SVC013` — Invalid Rollback Policy

**Status** — 400

The merged rollback policy specification is not valid.

**Resolution** — Check the rollback policy fields in the request body.

### `SVC014` — Invalid Healthcheck

**Status** — 400

The merged healthcheck specification is not valid.

**Resolution** — Check the healthcheck fields in the request body.

### `SVC015` — Config Missing Required Fields

**Status** — 400

Each config reference must include configID and configName.

**Resolution** — Provide both configID and configName for every config entry.

### `SVC016` — Secret Missing Required Fields

**Status** — 400

Each secret reference must include secretID and secretName.

**Resolution** — Provide both secretID and secretName for every secret entry.

### `SVC017` — Network Missing Target

**Status** — 400

Each network attachment must include a target network ID.

**Resolution** — Provide the target field for every network entry.

### `SVC018` — Invalid Patch Result

**Status** — 400

The JSON patch produced an invalid result that could not be applied.

**Resolution** — Check the patch operations for correctness.

### `SVC019` — Invalid Log Driver Specification

**Status** — 400

The merged log driver specification is not valid.

**Resolution** — Check the log driver name and options in the request body.

### `SVC020` — Port Missing Target

**Status** — 400

A published port must name the container port it forwards to.

**Resolution** — Set TargetPort to a non-zero container port for every port entry.

### `SVC021` — Unknown Attachment

**Status** — 400

A secret, config, or network the request attaches is not known to the cluster.

**Resolution** — Check the ID. A resource created outside Cetacean can take a moment to appear; retry shortly.

## TSK: Task operations

### `TSK001` — Task Already Removed

**Status** — 409

The task could not be removed because the Docker Engine no longer tracks it.

**Resolution** — The task may have already been cleaned up. Refresh the page to see the current state.

### `TSK002` — Task Not Found

**Status** — 404

The specified task does not exist.

**Resolution** — Check the task ID and try again. Tasks are ephemeral and may have been cleaned up.

## STK: Stack operations

### `STK001` — Stack Not Found

**Status** — 404

The specified stack does not exist. Stacks are derived from service labels and may disappear when all services in the stack are removed.

**Resolution** — Check the stack name and try again.

## VOL: Volume operations

### `VOL001` — Volume In Use

**Status** — 409

The volume cannot be removed because it is in use: a local volume is mounted by one or more containers, or a cluster volume is still published to a node.

**Resolution** — Stop or remove the containers or services using this volume first. Force removal does not override a container using a local volume, but deletes a cluster volume even while it is in use.

### `VOL002` — Volume Not Found

**Status** — 404

The specified volume does not exist.

**Resolution** — Check the volume name and try again.

## NET: Network operations

### `NET001` — Network Has Active Endpoints

**Status** — 409

The network cannot be removed because it has active endpoints from running containers or services.

**Resolution** — Disconnect or remove the services and containers attached to this network first.

### `NET002` — Network Not Found

**Status** — 404

The specified network does not exist.

**Resolution** — Check the network ID and try again.

## CFG: Config operations

### `CFG001` — Config In Use

**Status** — 409

The config cannot be removed because it is referenced by one or more services.

**Resolution** — Remove the config reference from all services before deleting it.

### `CFG002` — Config Not Found

**Status** — 404

The specified config does not exist.

**Resolution** — Check the config ID and try again.

### `CFG003` — Config Name Conflict

**Status** — 409

A config with this name already exists.

**Resolution** — Choose a different name or remove the existing config first.

### `CFG004` — Invalid Config

**Status** — 400

The config creation request is invalid.

**Resolution** — Provide a non-empty name and valid base64-encoded data.

### `CFG005` — Config Version Conflict

**Status** — 409

The config was modified concurrently.

**Resolution** — Retry the operation with the latest version.

## SEC: Secret operations

### `SEC001` — Secret In Use

**Status** — 409

The secret cannot be removed because it is referenced by one or more services.

**Resolution** — Remove the secret reference from all services before deleting it.

### `SEC002` — Secret Not Found

**Status** — 404

The specified secret does not exist.

**Resolution** — Check the secret ID and try again.

### `SEC003` — Secret Name Conflict

**Status** — 409

A secret with this name already exists.

**Resolution** — Choose a different name or remove the existing secret first.

### `SEC004` — Invalid Secret

**Status** — 400

The secret creation request is invalid.

**Resolution** — Provide a non-empty name and valid base64-encoded data.

### `SEC005` — Secret Version Conflict

**Status** — 409

The secret was modified concurrently.

**Resolution** — Retry the operation with the latest version.
