Vault defines sentinel errors in the root vault package. Use errors.Is to check for specific error conditions in your application code.
Using errors.Is01
import (
"errors"
"github.com/xraph/vault"
)
sec, err := secretSvc.Get(ctx, "my-key", "myapp")
if errors.Is(err, vault.ErrSecretNotFound) {
// secret does not exist for this app
}All Vault services return these sentinel errors. Store backends wrap them appropriately so that errors.Is works regardless of which backend is in use.
Sentinel errors by category02
Store errors
| Error | Value | Description |
vault.ErrNoStore | "vault: no store configured" | No store backend has been configured. |
Not-found errors
These are returned when a requested entity does not exist for the given key and app ID.
| Error | Value | Description |
vault.ErrKeyNotFound | "vault: key not found" | Generic key not found (used by source package). |
vault.ErrSecretNotFound | "vault: secret not found" | No secret with the given key exists for this app. |
vault.ErrFlagNotFound | "vault: flag not found" | No flag definition with the given key exists for this app. |
vault.ErrConfigNotFound | "vault: config entry not found" | No config entry with the given key exists for this app. |
vault.ErrOverrideNotFound | "vault: override not found" | No tenant override exists for the given key, app, and tenant. |
vault.ErrRotationNotFound | "vault: rotation policy not found" | No rotation policy exists for the given secret key and app. |
vault.ErrAuditNotFound | "vault: audit entry not found" | No audit entry with the given ID exists. |
vault.ErrRunNotFound | "vault: workflow run not found" | No workflow run with the given ID exists. |
vault.ErrDLQNotFound | "vault: DLQ entry not found" | No dead-letter queue entry with the given ID exists. |
vault.ErrCronNotFound | "vault: cron entry not found" | No cron entry with the given ID exists. |
vault.ErrEventNotFound | "vault: event not found" | No event with the given ID exists. |
vault.ErrWorkflowNotFound | "vault: workflow not found" | No workflow with the given ID exists. |
Cryptography errors
| Error | Value | Description |
vault.ErrDecryptionFailed | "vault: decryption failed" | Decryption of a secret value failed (wrong key or corrupted ciphertext). |
vault.ErrEncryptionFailed | "vault: encryption failed" | Encryption of a secret value failed. |
vault.ErrInvalidKey | "vault: invalid encryption key" | The provided encryption key is invalid (e.g. wrong length). |
The crypto package also defines its own error:
crypto.ErrInvalidKeySize // "crypto: key must be exactly 32 bytes for AES-256"Feature flag errors
| Error | Value | Description |
vault.ErrFlagDisabled | "vault: flag is disabled" | The flag definition has Enabled: false. |
vault.ErrFlagExists | "vault: flag already exists" | A flag with this key already exists for this app. |
vault.ErrInvalidFlagKey | "vault: invalid flag key" | The flag key is empty or malformed. |
Secret errors
| Error | Value | Description |
vault.ErrSecretExists | "vault: secret already exists" | A secret with this key already exists for this app. |
Config errors
| Error | Value | Description |
vault.ErrConfigExists | "vault: config entry already exists" | A config entry with this key already exists for this app. |
Rotation errors
| Error | Value | Description |
vault.ErrRotationFailed | "vault: rotation failed" | A secret rotation operation failed. |
Authorization errors
| Error | Value | Description |
vault.ErrUnauthorized | "vault: unauthorized" | The caller is not authorized to perform this operation. |
Source package errors
The source package defines its own not-found error:
source.ErrKeyNotFound // "source: key not found"This is returned when no source in a chain contains the requested key. The source.Database adapter converts vault.ErrConfigNotFound to source.ErrKeyNotFound automatically.
Error handling patterns03
Check for specific errors
sec, err := secretSvc.Get(ctx, "api-key", "myapp")
switch {
case errors.Is(err, vault.ErrSecretNotFound):
// key does not exist -- create it
case err != nil:
// unexpected error
default:
// success
}Flag evaluation with defaults
The type-safe flag.Service methods (Bool, String, Int, Float) return the default value on any error, including ErrFlagNotFound. This is intentional -- flag evaluation should never crash your application.
// Returns false (the default) if the flag does not exist, is disabled,
// or evaluation encounters any error.
enabled := flagSvc.Bool(ctx, "new-dashboard", false)If you need to distinguish between "flag not found" and "flag exists but evaluates to default", use the Engine.Evaluate method directly:
val, err := engine.Evaluate(ctx, "new-dashboard", "myapp")
if errors.Is(err, vault.ErrFlagNotFound) {
// flag definition does not exist
}Config with fallback
Similarly, config.Service type-safe accessors return the default value on error:
// Returns 50 if "rate-limit" is not found or has a type mismatch.
limit := configSvc.Int(ctx, "rate-limit", 50)Override resolution
The override.Resolver silently falls through when ErrOverrideNotFound is returned -- it returns the app-level config value instead. Only unexpected errors are propagated.
val, err := resolver.Resolve(ctx, "rate-limit", "myapp")
if errors.Is(err, vault.ErrConfigNotFound) {
// neither override nor app config exists
}Wrapped errors04
Service methods may wrap sentinel errors with additional context using fmt.Errorf and %w. Always use errors.Is rather than string comparison:
// Works correctly even if the error is wrapped.
if errors.Is(err, vault.ErrSecretNotFound) {
// ...
}