Abseil Canonical Status Error Codes: Complete Guide to absl::StatusCode Usage
The canonical absl::StatusCode enum defines 17 standardized error codes in absl/status/status.h that map to the gRPC/Google RPC error space, enabling portable error semantics across libraries and network boundaries.
The absl::Status class is the primary error‑handling type in the Abseil C++ library (abseil/abseil-cpp). Every non‑OK status carries a canonical error code that allows callers—whether in‑process or remote—to understand failure modes without parsing custom strings. These codes are defined in [absl/status/status.h](https://github.com/abseil/abseil-cpp/blob/master/absl/status/status.h) (lines 78‑104) and correspond directly to the Google RPC error space.
Canonical Status Error Codes Reference
The following table lists every absl::StatusCode value, its semantic meaning as documented in the Abseil source, and the specific scenario where it should be selected.
| Code | Meaning | When to Use |
|---|---|---|
kOk |
Success – not an error. | Return absl::OkStatus() or a default‑constructed absl::Status for successful operations. |
kCancelled |
The operation was cancelled, typically by the caller. | Use when a client explicitly aborts a request, such as cancelling a file download. |
kUnknown |
An unknown error occurred; used as a fallback. | Use only when the underlying system cannot provide a better classification. |
kInvalidArgument |
Caller supplied an invalid argument. | Use for validation failures that are intrinsic to the argument itself (e.g., malformed filename). |
kDeadlineExceeded |
A deadline expired before the operation could complete. | Use when a timeout is reached, even if the operation later completes successfully. |
kNotFound |
Requested entity (file, directory, etc.) was not found. | Use when a lookup fails because the target does not exist. |
kAlreadyExists |
The entity a caller tried to create already exists. | Use for “create” operations that would result in a duplicate. |
kPermissionDenied |
Caller lacks permission for the operation. | Use when the request is well‑formed but the caller is not authorized. |
kResourceExhausted |
Some resource has been exhausted. | Use for quota limits, out‑of‑memory conditions, or disk‑full scenarios. |
kFailedPrecondition |
System is not in a state required for the operation. | Use when the caller could correct the state, but a simple retry would not help (e.g., non‑empty directory for rmdir). |
kAborted |
Operation aborted due to a concurrency issue. | Use for optimistic‑concurrency failures (e.g., transaction conflicts) that require a higher‑level retry. |
kOutOfRange |
Operation attempted past a valid range. | Use when the error is range‑specific and the caller can advance to the next range (e.g., read past EOF). |
kUnimplemented |
Operation not implemented or supported. | Use for stubbed or platform‑specific features that are absent. |
kInternal |
Internal error – invariants violated. | Use for serious bugs that should be logged and alerted on immediately. |
kUnavailable |
Service temporarily unavailable (transient). | Use for transient failures where a retry with back‑off is appropriate. |
kDataLoss |
Unrecoverable data loss or corruption. | Use for catastrophic data‑integrity problems; attach alerts. |
kUnauthenticated |
Request lacks valid authentication credentials. | Use when the caller cannot be identified; differs from kPermissionDenied. |
Creating Statuses with Canonical Codes
Abseil provides convenience factory functions in absl/status/status.h to ensure consistency. These factories return an absl::Status with the appropriate canonical code and the provided message string.
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include <iostream>
absl::Status ReadFile(absl::string_view path) {
if (path.empty()) {
// Convenience factory for kInvalidArgument
return absl::InvalidArgumentError("path must not be empty");
}
// ... attempt to open file ...
if (!file_exists(path)) {
// Convenience factory for kNotFound
return absl::NotFoundError(absl::StrCat("file not found: ", path));
}
return absl::OkStatus();
}
Available factories include absl::CancelledError(), absl::UnknownError(), absl::DeadlineExceededError(), and others corresponding to each canonical code.
Checking Error Codes in Practice
To inspect a status without exposing the raw enum values, use the predicate helpers declared at lines 108‑136 of absl/status/status.h (e.g., absl::IsNotFound(), absl::IsInvalidArgument()). For complex dispatch, switch on status.code() directly.
absl::Status s = ReadFile("/tmp/data.txt");
// Method 1: Predicate helpers
if (absl::IsNotFound(s)) {
std::cerr << "Please create the file first.\n";
} else if (absl::IsInvalidArgument(s)) {
std::cerr << "Bad request: " << s.message() << "\n";
}
// Method 2: Switch on the canonical code
switch (s.code()) {
case absl::StatusCode::kPermissionDenied:
std::cerr << "Access denied.\n";
break;
case absl::StatusCode::kUnavailable:
std::cerr << "Service temporarily down; consider retry.\n";
break;
default:
std::cerr << "Unhandled error: " << s << "\n";
break;
}
Distinguishing Between Similar Codes
Several canonical codes describe overlapping failure modes. Select the most specific code to aid caller recovery.
kFailedPrecondition vs. kInvalidArgument
kInvalidArgument indicates that an argument is inherently invalid (e.g., negative size for a buffer) regardless of system state. kFailedPrecondition indicates the system is not in the required state for the operation (e.g., deleting a non‑empty directory), even though the argument itself might be valid in another context.
kPermissionDenied vs. kUnauthenticated
kUnauthenticated means the caller cannot be identified (e.g., missing or invalid credentials). kPermissionDenied means the caller is known but lacks authorization for the specific action. Return kUnauthenticated before checking permissions.
kUnavailable vs. kAborted
kUnavailable signals transient service disruptions (network timeouts, server downtime) where a retry with exponential back‑off is appropriate. kAborted signals concurrency failures (transaction conflicts) that require a higher‑level retry or reconciliation strategy, not just a simple re‑send.
Summary
- Prefer the most specific canonical
absl::StatusCodeavailable rather than generic fallbacks likekUnknown. - Use convenience factories (e.g.,
absl::NotFoundError()) defined inabsl/status/status.hto ensure consistency with the canonical codes. - Distinguish between caller errors (
kInvalidArgument,kNotFound) and system errors (kInternal,kUnavailable) when selecting codes. - Preserve canonical codes when propagating errors across RPC boundaries to maintain semantic meaning; use payloads for additional context if needed.
Frequently Asked Questions
What is the difference between kFailedPrecondition and kInvalidArgument?
kInvalidArgument indicates that an argument is inherently invalid (e.g., malformed syntax), regardless of system state. kFailedPrecondition indicates the system is not in the required state for the operation (e.g., deleting a non‑empty directory), even though the argument itself might be valid in another context.
When should I use kUnavailable instead of kAborted?
Use kUnavailable for transient service disruptions where a retry with back‑off is likely to succeed, such as network timeouts or server downtime. Use kAborted for concurrency failures like transaction conflicts that require a higher‑level retry or reconciliation strategy.
How do I check for specific error codes without comparing raw enum values?
Abseil provides predicate functions such as absl::IsNotFound(), absl::IsInvalidArgument(), and absl::IsUnavailable() declared in [absl/status/status.h](https://github.com/abseil/abseil-cpp/blob/master/absl/status/status.h) (lines 108‑136). These provide type‑safe checks without exposing the underlying StatusCode enum.
Can I define custom error codes beyond the canonical set?
No. The absl::StatusCode enum is closed and maps directly to the gRPC wire format. If you need application‑specific detail, attach a payload to the absl::Status object or use the message string, but keep the canonical code to ensure interoperability.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →