Errors — barbican — branch stable/2026.2
Branch
stable/2026.2@de32745a7a4f— repository https://opendev.org/openstack/barbican — analysed on 2026-10-29
1. Error body and translation
1.1 Body shapes
| Who answers | Body | Where |
|---|---|---|
Barbican (any webob.exc.HTTPError, including every pecan.abort) | {"code": <int>, "title": "<HTTP reason>", "description": "<text>"}, Content-Type: application/json | barbican/api/hooks.py:30 |
| keystonemiddleware (missing/invalid token) | {"error": {"code": 401, "title": "Unauthorized", "message": "The request you have made requires authentication."}} and WWW-Authenticate: Keystone uri="…" | keystonemiddleware; observed in _rewrite/observed-errors-functional_stable-2026.2.md |
context middleware (X-Identity-Status not Confirmed and anonymous access off, or no project in the token) | 401 webob page | barbican/api/middleware/context.py:66, barbican/api/middleware/context.py:85 |
unauthenticated pipeline without X-Project-Id | 400 Missing X-Project-Id | barbican/api/middleware/context.py:99 |
Pecan routing (no handler / generic index) | {"code": 405, "title": "Method Not Allowed", "description": ""}, or 404 | barbican/api/controllers/secrets.py:375 |
| oslo.middleware healthcheck | text / JSON per Accept | etc/barbican/barbican-api-paste.ini:59 |
Clients read title and description: python-barbicanclient builds "<title>: <description>" from the body (python-barbicanclient:barbicanclient/client.py:138).
1.2 Translation of exceptions (handle_exceptions)
Each handler carries an operation name (Secret creation, Secret payload retrieval…; see operation_name in _rewrite/routes_stable-2026.2.json). handle_exceptions (barbican/api/controllers/__init__.py:100) and generate_safe_exception_message (barbican/api/__init__.py:77) translate:
| Raised | Status | description |
|---|---|---|
webob.exc.HTTPError (e.g. pecan.abort(404, '…')) | its own | its own text, unchanged (barbican/api/controllers/__init__.py:108) |
oslo_policy.PolicyNotAuthorized / InvalidScope | 403 | "<Operation> attempt not allowed - please review your user/project privileges" (barbican/api/__init__.py:98) |
BarbicanHTTPException subclass | its status_code | "<Operation> issue seen - <client_message>." (barbican/api/__init__.py:105, barbican/api/__init__.py:112) |
anything else (incl. BarbicanException, NotFound, plugin errors, DB errors) | 500 | "<Operation> failure seen - please contact site administrator." (barbican/api/__init__.py:108) |
Two exceptions to this rule:
- errors raised while validating the body go through
load_body, which aborts with the exception's status and bareclient_message, without the operation prefix and without the trailing dot (barbican/api/__init__.py:69):POST /v1/secretswith a too-large payload answers413 "Provided information too large to process", whilePUT /v1/secrets/{id}answers413 "Secret update issue seen - Provided information too large to process."(both observed). client_messagevalues ending with a dot get a second one ("Secret update issue seen - No data supplied to process..", observed).
The full observed catalogue — 116 (operation, status, title, description) combinations from the functional run and 130 from the API unit tests — is in _rewrite/observed-errors-functional_stable-2026.2.md and _rewrite/observed-errors-api-tests_stable-2026.2.md.
2. Exceptions raised by the business code
2.1 barbican/common/exception.py
| Exception | HTTP | client_message / message | Situation | Raised at |
|---|---|---|---|---|
InvalidObject | 400 | Provided object does not match schema '{schema}': {reason}. Invalid property: '{property}' | body fails a JSON schema or a business check of a validator | barbican/common/validators.py:124, barbican/common/validators.py:135 |
UnsupportedField | 400 | Provided field value is not supported | order bit_length not a multiple of 8 / invalid EC size; container secret_ref not on this host | barbican/common/validators.py:545, barbican/common/validators.py:716 |
FeatureNotImplemented | 500 [no HTTP status: base BarbicanException] | Feature not implemented for value set on field … | order of an unknown type (certificate) | barbican/common/validators.py:561 |
LimitExceeded | 413 | Provided information too large to process | payload over max_allowed_secret_in_bytes | barbican/common/validators.py:315, barbican/api/controllers/secrets.py:236 |
NoDataToProcess | 400 | No data supplied to process. | empty body on PUT /v1/secrets/{id} or PUT /v1/project-quotas/{id} | barbican/api/controllers/secrets.py:234, barbican/api/controllers/quotas.py:90 |
SecretHasConsumers | 400 | Secret cannot be deleted as it has consumers. | microversion ≥ 1.2, consumers exist, no force | barbican/api/controllers/secrets.py:275 |
QuotaReached | 403 | Creation not allowed because a quota has been reached | count of the project's resources ≥ quota, or quota = 0 | barbican/common/quota.py:200 |
InvalidMetadataKey | 400 | Invalid Key. Key must be URL safe. | metadata key with characters outside [A-Za-z0-9_-] | barbican/common/validators.py:415 |
MissingMetadataField | 400 | Missing required metadata field for %(required)s | (helper, unused by the current order types) | barbican/common/validators.py:495 |
ProvidedTransportKeyNotFound | 400 | Provided Transport key %(transport_key_id)s could not be found | transport_key_id given at store time does not exist | barbican/plugin/resources.py:56 |
InvalidContainer | 400 | Invalid container: %(reason)s | stored-key RSA container reference invalid (helper) | barbican/common/validators.py:64 |
NotFound | 500 when it escapes | An object with the specified identifier was not found. | repository get without suppress_exception; most handlers catch it and abort 404 themselves | barbican/model/repositories.py:333 |
ConstraintCheck | 500 when it escapes | A defined SQL constraint check failed: %(error)s | duplicate key on insert (project creation race is caught) | barbican/model/repositories.py:369 |
Invalid | 500 | — | create_from with an entity that already has an id | barbican/model/repositories.py:349 |
MultipleStore* (5 classes) | 500 / start-up failure | see class | inconsistent [secretstore:*] configuration (no or several global_default, missing plugin value, store still preferred by a project) | barbican/plugin/util/multiple_backends.py:47, barbican/plugin/util/multiple_backends.py:100, barbican/plugin/util/multiple_backends.py:191 |
PKCS11Exception family | 500 | HSM returned response code: 0x… CKR_…, No token was found in slot %(slot_id)s, More than one key found for label, Could not find key labeled … | HSM call failed; the plugin re-initialises the library once and retries (barbican/plugin/crypto/p11_crypto.py:217) | barbican/plugin/crypto/pkcs11.py:923, barbican/plugin/crypto/p11_crypto.py:399 |
The certificate-authority exceptions (InvalidCAID, SubCA*, CannotDeletePreferredCA… barbican/common/exception.py:247–barbican/common/exception.py:322) and the CMC/PKCS#10 ones (barbican/common/exception.py:100–barbican/common/exception.py:143) have no raise site left in the API: they belong to the removed certificate feature.
2.2 Secret-store plugin layer (barbican/plugin/interface/secret_store.py)
| Exception | HTTP | client_message | Situation | Raised at |
|---|---|---|---|---|
SecretStorePluginNotFound | 400 | No plugin was found that could support your request | a transport key refers to a plugin that is not loaded | barbican/plugin/interface/secret_store.py:590 |
SecretStoreSupportedPluginNotFound | 400 | Secret store supported plugin not found. | no store accepts the key spec (or none offers a transport key) | barbican/plugin/interface/secret_store.py:603 |
SecretGenerateSupportedPluginNotFound | 400 | Secret generate supported plugin not found. | no store can generate the requested algorithm/size (order) | barbican/plugin/interface/secret_store.py:641 |
SecretContentTypeNotSupportedException | 400 | content-type of '…' not supported | normalised content type unsupported | barbican/plugin/util/translations.py:79, barbican/plugin/util/translations.py:117 |
SecretContentEncodingMustBeBase64 | 400 | Text-based binary secret payloads must specify a content-encoding of 'base64' | binary type with another encoding on POST | barbican/plugin/util/translations.py:65 |
SecretAcceptNotSupportedException | 406 | Wrong payload content-type | Accept not supported, or text/plain requested for non-UTF-8 bytes | barbican/plugin/util/translations.py:86, barbican/plugin/util/translations.py:103 |
SecretNotFoundException | 404 | Secret not found. | store_crypto asked for a secret without encrypted_data | barbican/plugin/store_crypto.py:116 |
SecretAlgorithmNotSupportedException | 400 | Requested algorithm is not supported | algorithm unknown to store_crypto/KMIP/castellan | barbican/plugin/store_crypto.py:162, barbican/plugin/store_crypto.py:274 |
GeneratePassphraseNotSupportedException | 400 | passphrase not supported | asymmetric order with passphrase on a castellan store | barbican/plugin/castellan_secret_store.py:183 |
StorePluginNotAvailableOrMisconfigured | 500 | — | the plugin_name stored with a secret is not loaded any more (configuration changed) | barbican/plugin/interface/secret_store.py:624 |
SecretStorePluginsNotConfigured | 500 | — | no secret-store plugin loaded | barbican/plugin/interface/secret_store.py:549 |
SecretGeneralException | 500 | — | back-end failure (KMIP, Vault, castellan) | barbican/plugin/castellan_secret_store.py:129, barbican/plugin/kmip_secret_store.py:401 |
SecretNoPayloadProvidedException | 500 | — | empty payload reached normalisation (should be prevented by validation) | barbican/plugin/util/translations.py:43 |
2.3 Crypto plugin layer (barbican/plugin/crypto/base.py)
| Exception | Situation | Raised at |
|---|---|---|
CryptoPluginNotFound → 500 Crypto plugin not found. | no crypto plugin instantiated (e.g. simple_crypto without [simple_crypto_plugin] kek: the constructor raises ValueError("SimpleCrypto KEK is undefined"), logged, plugin skipped) | barbican/plugin/crypto/manager.py:93, barbican/plugin/crypto/simple_crypto.py:60 |
CryptoPluginUnsupportedOperation → 500 | no plugin supports the type/algorithm/size, or the plugin that encrypted a secret (kek_data.plugin_name) is not loaded | barbican/plugin/crypto/manager.py:107, barbican/plugin/crypto/manager.py:130 |
CryptoKEKBindingException → 500 | bind_kek_metadata returned None | barbican/plugin/store_crypto.py:295 |
CryptoPrivateKeyFailureException → 500 | asymmetric generation with an algorithm other than RSA/DSA | barbican/plugin/crypto/simple_crypto.py:156 |
cryptography.fernet.InvalidToken → 500 | wrong master KEK, wrong project KEK, tampered ciphertext (simple_crypto) | barbican/plugin/crypto/simple_crypto.py:79, barbican/plugin/crypto/simple_crypto.py:102 |
NotImplementedError → 500 | asymmetric generation on PKCS#11 | barbican/plugin/crypto/p11_crypto.py:198 |
3. pecan.abort sites (controller-level errors)
| Status | Description | Where |
|---|---|---|
| 404 | Secret not found. / Not Found. Provided secret id is invalid. | barbican/api/controllers/secrets.py:43, barbican/api/controllers/secrets.py:48 |
| 404 | Not Found. Sorry but your secret has no payload. | barbican/api/controllers/secrets.py:53 |
| 409 | Secret already has data, cannot modify it. | barbican/api/controllers/secrets.py:58 |
| 400 | URI provided invalid query string parameters. (date filters, sort, force) | barbican/api/controllers/secrets.py:62 |
| 400 | Transport key wrapped session key has been provided to wrap secrets for retrieval, but the transport key id has not been provided. | barbican/api/controllers/secrets.py:71 |
| 415 | Content-Type of '<type>' is not supported for PUT. / Unexpected content type. Expected content types are: [...] | barbican/api/controllers/secrets.py:224, barbican/api/controllers/__init__.py:145 |
| 405 | (empty) — wrong method; /payload with non-GET; metadata item with POST | barbican/api/controllers/secrets.py:111, barbican/api/controllers/secrets.py:205, barbican/api/controllers/secrets.py:104 |
| 404 | unknown sub-resource of a secret (/v1/secrets/{id}/xyz) | barbican/api/controllers/secrets.py:107 |
| 404 | Secrets container not found. / Not Found. Provided container id is invalid. | barbican/api/controllers/containers.py:36, barbican/api/controllers/containers.py:41 |
| 404 | Secret provided for '<name>' doesn't exist. / Secret provided doesn't exist. / Secret provided is not in the container | barbican/api/controllers/containers.py:206, barbican/api/controllers/containers.py:260, barbican/api/controllers/containers.py:318 |
| 400 | Only 'generic' containers can be modified. | barbican/api/controllers/containers.py:247 |
| 409 | Conflict. A secret with that name and ID is already stored in this container. … | barbican/api/controllers/containers.py:268 |
| 404 | Order not found.; 405 Order update is not supported. | barbican/api/controllers/orders.py:32, barbican/api/controllers/orders.py:42 |
| 404 | Consumer not found. / Not Found. Provided consumer id is invalid. | barbican/api/controllers/consumers.py:33, barbican/api/controllers/consumers.py:44 |
| 403 | Not Allowed. Sorry, only the creator of a consumer can delete it. | barbican/api/controllers/consumers.py:38 |
| 404 | Secret metadata not found.; 409 Conflict. Key in request is already in the secret metadata; 409 Key in request data does not match key in the request url. | barbican/api/controllers/secretmeta.py:28, barbican/api/controllers/secretmeta.py:95, barbican/api/controllers/secretmeta.py:158 |
| 404 | Project quotas not found. | barbican/api/controllers/quotas.py:32 |
| 404 | Not Found. Secret store not found. / … No preferred secret store defined for this project. / … Multiple backends support is not enabled in service configuration. | barbican/api/controllers/secretstores.py:30, barbican/api/controllers/secretstores.py:35, barbican/api/controllers/secretstores.py:41 |
| 404 | Not Found. Transport Key not found. / … Provided transport key id is invalid. | barbican/api/controllers/transportkeys.py:33, barbican/api/controllers/transportkeys.py:38 |
| 400 / 500 | Malformed JSON / Read Error | barbican/api/__init__.py:65, barbican/api/__init__.py:55 |
| 404 | The version you requested wasn't found | barbican/api/controllers/versions.py:77 |
Note the message Order update is not supported. exists but PUT /v1/orders/{id} does not reach it: OrderController has no PUT handler, so Pecan answers a bare 405 (observed PUT /v1/orders/<id> → 401/405).
4. Errors outside the API
| Where | Situation | What happens | Seen by |
|---|---|---|---|
order task (BeginTypeOrder) | generation fails (plugin not found, HSM error, unsupported algorithm…) | order set to ERROR with error_status_code and error_reason built like an API message ("Process TypeOrder issue seen - …" or "… failure seen - please contact site administrator."), exception suppressed so the status is committed (barbican/tasks/resources.py:102, barbican/tasks/resources.py:189, barbican/tasks/resources.py:45) | GET /v1/orders/{id}; castellan raises KeyManagerError("Order is in ERROR status - status code: …, status reason: …") (castellan:castellan/key_manager/barbican_key_manager.py:526) |
| order task without a worker | any exception | logged >>>>> Task exception seen for synchronous task invocation… and swallowed (barbican/queue/client.py:79) | order stays PENDING if the failure happened before handle_error |
worker transactional wrapper | unexpected exception | LOG.exception("Problem seen processing worker task: …"), rollback (barbican/queue/server.py:96) | order stays PENDING |
| retry scheduler | enqueue fails | Problem enqueuing method …, rollback, task kept for the next cycle (barbican/queue/retry_scheduler.py:155) | logs |
| Keystone listener | cleanup fails | rollback; REQUEUE if [keystone_notifications] allow_requeue, else HANDLED (message dropped) (barbican/queue/keystone_listener.py:100); the handle_error log itself fails with AttributeError on project.project_id (barbican/tasks/keystone_consumer.py:79) | logs |
| PKCS#11 | token removed / library error | LOG.warning("Reinitializing PKCS#11 library: …"), one retry (barbican/plugin/crypto/p11_crypto.py:218) | 500 if the retry fails |
| API start | DB unreachable, secret-store sync fails | LOG.exception('Failed to sync secret_stores table.'), the app does not start (barbican/api/app.py:90) | deployment |
| keystone-listener start | [keystone_notifications] enable = False | logs Exiting as Barbican Keystone listener is not enabled... and exits 0 (barbican/cmd/keystone_listener.py:59) | deployment |
Source: reverse-spec-barbican/02-errors_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.