Error handling
Cloud API error responses use Content-Type: application/problem+json. Branch on type. title, detail, and hint are the human-readable text.
A missing token on GET /iam/clients/me is a different body, Content-Type: application/json:
{
"message": "Authentication credentials were not provided.",
"code": "not_authenticated"
}
Error response fields
Every Cloud API error body in this article includes these fields:
| Field | Description |
|---|---|
type | Stable code. Branch on this value. |
title | Fixed sentence for that type. |
status | HTTP status code, repeated in the body. |
detail | What happened on this call. |
hint | What to do next. |
request_id | Same value as the X-Request-Id response header. |
trace_id | Trace id. It is the second field of the traceparent response header. |
Some bodies also include the fields below.
| Field | When it appears |
|---|---|
errors | validation-error. One item per invalid input: loc, code, detail, and sometimes ctx. |
context | Extra data for the type. Resource errors include resource_type and resource_id. method-not-allowed includes allowed_methods. |
exception_class | Previous name of the error. Branch on type. |
message | Previous text of the error. |
invalid_fields | Previous field map on some validation responses. Read errors. |
type, errors[].code, and loc stay the same in every language. exception_class stays the same as well.
unauthorized
A request with no Authorization header returns HTTP 401:
{
"type": "unauthorized",
"title": "The request has no valid credentials.",
"status": 401,
"detail": "The request has no API key and no token.",
"hint": "Send the header 'Authorization: apikey <api_token>' with a valid token. If you have no token, create an API token first.",
"request_id": "c5fc3b9e7a09a3661ee2a5c0f9d18674",
"trace_id": "40dcb19aad763c6b66855e82d814b9c3",
"exception_class": "UnauthorizedError",
"message": "The request has no API key and no token."
}
detail identifies which credential failure this is:
detail | Cause |
|---|---|
The request has no API key and no token. | No Authorization header |
The API key or the token is not valid. | The header was sent, and the token is not valid |
Create an API token when the account has none. Send it on later calls as Authorization: APIKey $GCORE_API_KEY.
validation-error
HTTP 400. errors lists each invalid input. loc is the path to that input. In the responses below it starts with body. code names the failed check.
A create-volume call with "source": "new-volume" and no size returns:
{
"type": "validation-error",
"title": "The request has invalid input.",
"status": 400,
"detail": "1 input is not valid.",
"hint": "Correct each input in 'errors', then send the request again.",
"request_id": "0f43199b2960322c34cb5b4c94d652b8",
"trace_id": "53428bb45062e7df50bb06144538c2fd",
"errors": [
{
"loc": ["body", "size"],
"code": "missing",
"detail": "The field is required."
}
],
"exception_class": "ValidationError",
"message": "'size': The field is required.",
"invalid_fields": {
"new-volume": {
"size": ["Field required"]
}
}
}
invalid_fields on this response is grouped under new-volume, the source value. errors[].loc is the path to read. Correct size, then send the call again. The same body sent again returns the same 400.
A body that is not JSON is also validation-error. The item then has "code": "json_invalid" and "loc": ["body"].
Another validation item can include ctx. An empty object sent to the same endpoint returned "code": "union_tag_not_found" and "ctx": {"discriminator": "'source'"}.
not-found
HTTP 404. A volume id that does not exist returns:
{
"type": "not-found",
"title": "The resource does not exist.",
"status": 404,
"detail": "The volume '00000000-0000-4000-8000-000000000001' does not exist.",
"hint": "Check the ID, or list the volumes to find it.",
"request_id": "fab9270b14372990f2c596fc67992aa6",
"trace_id": "ed27d90f421793327f0a0768e2fdaa12",
"context": {
"resource_type": "volumes",
"resource_id": "00000000-0000-4000-8000-000000000001"
},
"exception_class": "NotFoundError",
"message": "The volume '00000000-0000-4000-8000-000000000001' does not exist."
}
context.resource_type and context.resource_id name the missing resource. Check the id, the project, and the region, then list that resource.
A path that matches no endpoint is also not-found, with no context, exception_class, or message:
{
"type": "not-found",
"title": "The resource does not exist.",
"status": 404,
"detail": "The URL does not match an endpoint.",
"hint": "Check the URL.",
"request_id": "e04bb04f06a8506dba5b687bb1df4fd5",
"trace_id": "e4e650e2a4121cefbc03b45f549a1bbc"
}
method-not-allowed
HTTP 405. PATCH on the volume collection returns:
{
"type": "method-not-allowed",
"title": "The endpoint does not support the method.",
"status": 405,
"detail": "The endpoint does not support 'PATCH'.",
"hint": "Use one of the methods in 'allowed_methods'.",
"request_id": "d42d9a180a2268e3f9f9e3c1c89d8df5",
"trace_id": "392f25fddd27c0183a4bb6c6a088cbae",
"context": {
"allowed_methods": ["GET", "POST"]
}
}
This response has no exception_class or message. The Allow header on the same response is GET, POST, matching context.allowed_methods.
Language
Send Accept-Language to select the language of title, detail, and hint. The response sets Content-Language to that language and sends Vary: Accept-Language. With no Accept-Language, Content-Language is en.
ru, de, zh, and az each returned translated title, detail, and hint for an unknown URL. The same create-volume validation with Accept-Language: ru returns:
{
"type": "validation-error",
"title": "Запрос содержит недопустимые входные параметры.",
"status": 400,
"detail": "1 входной параметр недопустим.",
"hint": "Исправьте каждый входной параметр в 'errors', затем отправьте запрос снова.",
"request_id": "fb5fe140dc868b4233f489f7ae60044a",
"trace_id": "7a0860c6f68acdd99a4bd5114721e503",
"errors": [
{
"loc": ["body", "size"],
"code": "missing",
"detail": "Поле обязательно."
}
],
"exception_class": "ValidationError",
"message": "'size': Поле обязательно.",
"invalid_fields": {
"new-volume": {
"size": ["Field required"]
}
}
}
errors[].detail and message are Russian. invalid_fields stays English (Field required). type, code, and loc are unchanged.
Next step
type | Action |
|---|---|
unauthorized | Send a valid API token in Authorization. |
validation-error | Correct every item in errors, then send the request again. |
not-found | Check the id in context, or check the URL when context is absent. |
method-not-allowed | Call again with a method from context.allowed_methods. |
Include request_id when contacting CDB support.