44
55syntax = "proto3" ;
66
7- package kurrentdb.protocol.v2.common.errors ;
7+ package kurrent.rpc ;
88
99option go_package = "github.com/kurrent-io/KurrentDB-Client-Go/protos/kurrentdb/protocols/v2/common/errors" ;
1010option csharp_namespace = "KurrentDB.Protocol.V2.Common.Errors" ;
@@ -13,138 +13,143 @@ option java_multiple_files = true;
1313
1414import "kurrentdb/protocol/v2/rpc.proto" ;
1515
16- enum CommonError {
16+ // The canonical server error codes for the Kurrent Platform gRPC APIs.
17+ // These errors represent common failure modes across all Kurrent services.
18+ enum ServerError {
1719 // Default value. This value is not used.
1820 // An error code MUST always be set to a non-zero value.
1921 // If an error code is not explicitly set, it MUST be treated as
2022 // an internal server error (INTERNAL).
2123 UNSPECIFIED = 0 ;
2224
23- COMMON_ERROR_ACCESS_DENIED = 1 [(kurrent.rpc.error ) = {
25+ // Authentication or authorization failure.
26+ // The client lacks valid credentials or sufficient permissions to perform the requested operation.
27+ //
28+ // Common causes:
29+ // - Missing or invalid authentication tokens
30+ // - Insufficient permissions for the operation
31+ // - Expired credentials
32+ //
33+ // Client action: Check credentials, verify permissions, and re-authenticate if necessary.
34+ // Not retriable without fixing the underlying authorization issue.
35+ SERVER_ERROR_ACCESS_DENIED = 1 [(kurrent.rpc.error ) = {
2436 status_code : PERMISSION_DENIED,
2537 has_details : true
2638 }];
2739
28- COMMON_ERROR_INVALID_REQUEST = 2 [(kurrent.rpc.error ) = {
40+ // The request is malformed or contains invalid data.
41+ // The server cannot process the request due to client error.
42+ //
43+ // Common causes:
44+ // - Invalid field values (e.g., empty required fields, out-of-range numbers)
45+ // - Malformed data formats
46+ // - Validation failures
47+ //
48+ // Client action: Fix the request data and retry.
49+ // Not retriable without modifying the request.
50+ SERVER_ERROR_BAD_REQUEST = 2 [(kurrent.rpc.error ) = {
2951 status_code : INVALID_ARGUMENT,
3052 has_details : true
3153 }];
3254
33- COMMON_ERROR_NOT_LEADER_NODE = 5 [(kurrent.rpc.error ) = {
55+ // The server is not the cluster leader and cannot process write operations.
56+ // In a clustered deployment, only the leader node can accept write operations.
57+ //
58+ // Common causes:
59+ // - Client connected to a follower node
60+ // - Leader election in progress
61+ // - Network partition
62+ //
63+ // Client action: Redirect the request to the leader node indicated in the error details.
64+ // Retriable after redirecting to the correct leader node.
65+ SERVER_ERROR_NOT_LEADER_NODE = 5 [(kurrent.rpc.error ) = {
3466 status_code : FAILED_PRECONDITION,
3567 has_details : true
3668 }];
3769
38- COMMON_ERROR_OPERATION_TIMEOUT = 6 [(kurrent.rpc.error ) = {
70+ // The operation did not complete within the configured timeout period.
71+ //
72+ // Common causes:
73+ // - Slow disk I/O during writes
74+ // - Cluster consensus delays
75+ // - Network latency
76+ // - Heavy server load
77+ //
78+ // Client action: Retry with exponential backoff. Consider increasing timeout values.
79+ // Retriable - the operation may succeed on retry.
80+ SERVER_ERROR_OPERATION_TIMEOUT = 6 [(kurrent.rpc.error ) = {
3981 status_code : DEADLINE_EXCEEDED
4082 }];
4183
42- COMMON_ERROR_SERVER_NOT_READY = 7 [(kurrent.rpc.error ) = {
84+ // The server is starting up or shutting down and cannot process requests.
85+ //
86+ // Common causes:
87+ // - Server is initializing (loading indexes, recovering state)
88+ // - Server is performing graceful shutdown
89+ // - Server is performing maintenance operations
90+ //
91+ // Client action: Retry with exponential backoff. Wait for server to become ready.
92+ // Retriable - the server will become available after initialization completes.
93+ SERVER_ERROR_SERVER_NOT_READY = 7 [(kurrent.rpc.error ) = {
4394 status_code : UNAVAILABLE
4495 }];
4596
46- COMMON_ERROR_SERVER_OVERLOADED = 8 [(kurrent.rpc.error ) = {
97+ // The server is temporarily overloaded and cannot accept more requests.
98+ // This is a backpressure mechanism to prevent server overload.
99+ //
100+ // Common causes:
101+ // - Too many concurrent requests
102+ // - Resource exhaustion (CPU, memory, disk I/O)
103+ // - Rate limiting triggered
104+ //
105+ // Client action: Retry with exponential backoff. Reduce request rate.
106+ // Retriable - the server may accept requests after load decreases.
107+ SERVER_ERROR_SERVER_OVERLOADED = 8 [(kurrent.rpc.error ) = {
47108 status_code : UNAVAILABLE
48109 }];
49110
50- COMMON_ERROR_SERVER_MALFUNCTION = 9 [(kurrent.rpc.error ) = {
111+ // An internal server error occurred.
112+ // This indicates a bug or unexpected condition in the server.
113+ //
114+ // Common causes:
115+ // - Unhandled exceptions
116+ // - Assertion failures
117+ // - Corrupted internal state
118+ // - Programming errors
119+ //
120+ // Client action: Report to server administrators with request details.
121+ // May be retriable, but likely indicates a server-side issue requiring investigation.
122+ SERVER_ERROR_SERVER_MALFUNCTION = 9 [(kurrent.rpc.error ) = {
51123 status_code : INTERNAL
52124 }];
53-
54- // // The operation was aborted, typically due to a concurrency issue such as a
55- // // sequencer conflict or transaction abort.
56- // // This error will only be used when there is no intention to create a dedicated
57- // // error code for the specific issue, perhaps because the issue is too generic
58- // // or too transient or temporary in terms of handling.
59- // OPERATION_ABORTED = 10 [(kurrent.rpc.error) = {
60- // status_code: ABORTED
61- // }];
62125}
63126
127+ // Details for ACCESS_DENIED errors.
64128message AccessDeniedErrorDetails {
65- // The scope in which access was denied.
66- // It could represent a resource, a domain, a permission type
67- // or a "path" that is a combination of these.
68- // (e.g., "stream:orders", "db:customers:read", etc.)
69- optional string scope = 1 ;
129+ // The friendly name of the operation that was denied.
130+ string operation = 1 ;
70131
71132 // The username of the user who was denied access.
72133 optional string username = 2 ;
73- }
74134
75- message InvalidRequestErrorDetails {
76- // Detailed information about each invalid argument.
77- repeated FieldViolation violations = 1 ;
78-
79- // Describes a single field violation.
80- message FieldViolation {
81- // A path that leads to a field in the request body. The value will be a
82- // sequence of dot-separated identifiers that identify a protocol buffer
83- // field.
84- //
85- // Consider the following:
86- //
87- // message CreateContactRequest {
88- // message EmailAddress {
89- // enum Type {
90- // TYPE_UNSPECIFIED = 0;
91- // HOME = 1;
92- // WORK = 2;
93- // }
94- //
95- // optional string email = 1;
96- // repeated EmailType type = 2;
97- // }
98- //
99- // string full_name = 1;
100- // repeated EmailAddress email_addresses = 2;
101- // }
102- //
103- // In this example, in proto `field` could take one of the following values:
104- //
105- // * `full_name` for a violation in the `full_name` value
106- // * `email_addresses[1].email` for a violation in the `email` field of the
107- // first `email_addresses` message
108- // * `email_addresses[3].type[2]` for a violation in the second `type`
109- // value in the third `email_addresses` message.
110- //
111- // In JSON, the same values are represented as:
112- //
113- // * `fullName` for a violation in the `fullName` value
114- // * `emailAddresses[1].email` for a violation in the `email` field of the
115- // first `emailAddresses` message
116- // * `emailAddresses[3].type[2]` for a violation in the second `type`
117- // value in the third `emailAddresses` message.
118- string field = 1 ;
119-
120- // A description of why the request element is bad.
121- string description = 2 ;
122- }
135+ // The permission that was required for this operation.
136+ optional string permission = 3 ;
123137}
124138
139+ // Details for NOT_LEADER_NODE errors.
125140message NotLeaderNodeErrorDetails {
126- // The host of the current leader node
127- string host = 1 ;
141+ // Information about the current cluster leader node.
142+ NodeInfo current_leader = 1 ;
128143
129- // The port of the current leader node
130- int32 port = 2 ;
144+ // Information about a cluster node.
145+ message NodeInfo {
146+ // The hostname or IP address of the node.
147+ string host = 1 ;
131148
132- // The instance ID of the current leader node
133- optional string node_id = 3 ;
134- }
149+ // The gRPC port of the node.
150+ int32 port = 2 ;
135151
136- message RetryInfoErrorDetails {
137- // The duration in milliseconds after which the client can retry the operation.
138- int32 retry_delay_ms = 1 ;
139- }
140-
141- message NodeInfoErrorDetails {
142- // The host of the node
143- string host = 1 ;
144-
145- // The port of the node
146- int32 port = 2 ;
147-
148- // The instance ID of the node
149- optional string node_id = 3 ;
152+ // The unique instance ID of the node.
153+ optional string node_id = 3 ;
154+ }
150155}
0 commit comments