Errors
How the current agrirouter API returns errors, plus reference for legacy error codes
agrirouter has two API surfaces with very different error conventions. The current API returns plain human-readable JSON messages. The legacy API returns numeric codes inside a protobuf envelope. This page covers both.
Do not surface agrirouter error messages one-to-one to end users. Wrap them with application-specific context so the guidance is meaningful in your UI.
Every error response on the current API has the same shape:
{
"message": "A human-readable description of the error."
}There is no numeric code field on the wire. Branch on the HTTP status code; the message string carries the human-readable detail. Values like message IDs or endpoint IDs are already substituted into the text, so you can log it directly or wrap it in your own UI copy.
HTTP status codes
The current API uses the following status codes across its endpoints. Individual endpoint pages list which statuses apply to that endpoint.
| Status | Meaning |
|---|---|
200 | The request succeeded. |
204 | The request succeeded and there is no response body (typical for DELETE /endpoints/{externalId}). |
400 | The request is invalid (malformed headers, missing required fields, unsupported message type), or, for POST /messages, no route exists from the sender to a specified direct recipient. |
401 | The access token is missing, expired, or otherwise not valid. |
403 | The endpoint ID in the request header does not belong to a tenant that the caller's access token is authorized for. |
404 | The requested endpoint, message, or resource does not exist. |
413 | The payload exceeds the 256 MB size limit. |
429 | The application has exceeded its per-application request rate. Back off and retry. See Rate limits. |
5xx | An internal error in agrirouter. Retry with exponential backoff. |
Check the agrirouter status page at agrirouter.statuspage.io for ongoing incidents or maintenance windows before investigating 5xx responses in your own integration.
Rate limits
Request limits are enforced per application across all its endpoints. When the limit is exceeded, the gateway responds with HTTP 429 and a plain { "message": "rate limit exceeded" } body. The response does not include a Retry-After header, so client code should fall back to its own exponential backoff.
Concrete limits vary by environment and application tier and may change over time. For the current limit for your application, write to support@agrirouter.com.
Relationship to the legacy codes
Internally, agrirouter still runs the same validation logic that produces the legacy VAL_000XXX and SYS_000XXX codes listed below. On the current API, the numeric code is stripped before the response goes out, and only the human-readable message reaches the wire. That means:
- You cannot distinguish
VAL_000004("all routes failed") fromVAL_000005("some routes failed") from the status line alone. Both surface as HTTP400with a plain{ "message": "..." }body. - Your code should rely on the HTTP status and, where disambiguation matters, on pattern-matching the message string. It should not attempt to parse numeric codes out of the JSON body.
Legacy API error codes
The numeric codes in the tables below are returned only by the Legacy API in its protobuf response envelope. The current API strips these codes and returns only the { "message": "..." } body described above. They are kept here as a reference for partners maintaining legacy integrations.
Message placeholders
Legacy error messages may contain the following placeholders, which agrirouter replaces with actual values at runtime:
| Placeholder | Description |
|---|---|
%messageId% | The internal agrirouter message ID |
%applicationMessageId% | The message ID assigned by your application |
%technicalMessageType% | The technical message type of the message |
%endpoints% | The affected endpoint IDs |
%chunkContextId% | The chunk context ID for chunked messages |
%chunkNumber% | The current chunk number |
%chunkTotal% | The total number of chunks |
Error categories
System errors point to internal agrirouter issues. If they persist, check the status page or contact support.
| Code | Message | Description |
|---|---|---|
SYS_000001 | Unexpected internal error for message %messageId% | An internal system error occurred. Retry the request; if it persists, contact support. |
These errors point to problems with the format or content of your request.
| Code | Message | Description |
|---|---|---|
VAL_000001 | Malformed request: protobuf/json can not be parsed for message %messageId% | The request body could not be parsed. Check that your protobuf or JSON encoding is correct. |
VAL_000002 | Malformed message header for message %messageId% | One or more required header fields are missing or invalid. |
VAL_000003 | Unsupported message for message %messageId% of type %technicalMessageType% | The technical message type is not recognized. Verify the type string. |
VAL_000004 | All routings failed for message %applicationMessageId% of type %technicalMessageType% | No route delivered the message. |
VAL_000005 | Some routings failed for message %applicationMessageId% of type %technicalMessageType% | The message was delivered to some but not all intended recipients. |
VAL_000006 | Publish only, no error even if no partner found | The message was published without a specific recipient. No error is raised even if no recipient receives it. |
VAL_000007 | No recipients found for message %applicationMessageId% of type %technicalMessageType% | No valid recipients could be resolved. Ensure endpoints are reachable and routes exist. |
VAL_000008 | Message %applicationMessageId% could not be delivered to endpoint %endpoints% | Delivery failed for the specified endpoints. The endpoints may be offline or unreachable. |
VAL_000009 | Duplicate message %applicationMessageId% | A message with this application message ID was already processed. Use unique IDs. |
VAL_000010 | Message %applicationMessageId% exceeds maximum size | The message payload exceeds the maximum request size. Reduce the payload size. |
VAL_000011 | Chunk %chunkNumber% of %chunkTotal% for context %chunkContextId% is invalid | A chunk in the sequence is malformed or out of order. Resend the complete chunk sequence. |
VAL_000012 | Chunk context %chunkContextId% has expired | The chunked transfer took too long and the context expired. Resend all chunks. |
VAL_000013 | Chunk %chunkNumber% of %chunkTotal% for context %chunkContextId% already received | This chunk was already uploaded. Do not resend chunks that have been acknowledged. |
These errors relate to subscription and capability configuration.
| Code | Message | Description |
|---|---|---|
VAL_000050 | Subscription for %technicalMessageType% not valid | The subscription for this message type is not valid or has not been set up. |
VAL_000051 | Capability for %technicalMessageType% not valid | The endpoint does not have the required capability for this message type. Update your capabilities declaration. |
VAL_000052 | Sending of %technicalMessageType% not allowed | The endpoint is not permitted to send this message type. Check your capability configuration. |
Onboarding errors occur during the legacy endpoint registration process.
| Code | Message | Description |
|---|---|---|
VAL_000201 | Registration code is invalid | The registration code (TAN) is not valid. It may have expired or already been used. |
VAL_000202 | Registration code has expired | The TAN has expired. Request a new one. |
VAL_000203 | Endpoint already exists | An endpoint with this external ID already exists for this tenant and application. |
VAL_000204 | Application not found | The application ID does not match any registered application. |
VAL_000205 | Certification not found | The certificationVersionId from your legacy onboarding request could not be resolved. Verify the value issued to your application in the developer portal. |
VAL_000206 | Onboarding request is invalid | The onboarding request body is malformed or missing required fields. |
VAL_000207 | Gateway type not supported | The requested gateway type (MQTT/HTTP) is not supported for this operation. |
VAL_000208 | Reonboarding not possible | The endpoint cannot be reonboarded. It may have been permanently revoked. |
VAL_000209 | Revoke not possible | The endpoint cannot be revoked in its current state. |
Errors related to Virtual CUs (VCUs) and device management.
| Code | Message | Description |
|---|---|---|
VAL_000300 | VCU onboarding failed | The Virtual CU could not be onboarded. Check the parent endpoint and permissions. |
VAL_000301 | VCU not found | The specified VCU does not exist or is not accessible. |
VAL_000302 | VCU limit reached | The maximum number of VCUs for this endpoint has been reached. |
VAL_000303 | Not allowed to send message type %technicalMessageType% | The VCU is not allowed to send this message type. This occurs when registering a VCU on an endpoint that is not a telemetry platform endpoint. |
Troubleshooting legacy responses
- SYS errors: server-side. Retry with exponential backoff. If they persist, check the status page.
- VAL_000001–VAL_000003: double-check your message encoding and header fields.
- VAL_000004 and VAL_000005: review your route configuration in the agrirouter UI. On the current API, both complete and partial routing failures surface as HTTP
400with a plain message body, so the numeric distinction is only visible on the legacy wire. - VAL_000201–VAL_000209: check your legacy onboarding flow. TANs must be fresh and application IDs correct.
- VAL_000303: typically means you are trying to use a VCU capability on an endpoint that is not a telemetry platform endpoint.