Error Codes¶
Every UBI public API function returns either 0 on success or a
negative standard errno value on failure. This page enumerates
each value: when UBI returns it, what it means at the application
layer, and how the application is expected to react.
The table is the lookup view; the sections below add per-code recovery notes for the cases where “what to do” is not obvious.
Lookup table¶
Code |
Returned by |
Meaning |
Recommended reaction |
|---|---|---|---|
|
every public function |
NULL pointer, bad parameter, geometry mismatch ( |
Programmer error — fix the caller. Do not retry. |
|
|
Volume with given |
Treat as “not found”. Re-create the volume or skip the operation. |
|
|
A volume with the requested name already exists with a different configuration (type or |
Decide intent: either accept the existing config or remove + recreate. Same name + identical config returns |
|
|
No free PEB available, or |
Run |
|
every mutating call when the device is in degraded read-only mode |
Reserved-PEB redundancy is lost (only 1 active reserved PEB, no spares) or the secure backend has latched a strict-RO policy |
Reads remain available. Call |
|
every flash-touching call |
Underlying |
Retry once. Persistent |
|
every allocating call |
Memory backend is exhausted: static slab pools full (raise |
Programmer error in capacity planning. Re-tune the static pools or the application heap. |
|
|
Another |
Re-use the existing handle, or call |
|
|
Operation is not applicable: resize on a static volume, or |
Not an error per se. The caller asked for a no-op. |
|
|
A required secure-mode platform capability (PSA |
Adjust Kconfig: enable PSA Crypto and entropy. Secure UBI cannot be brought up without these. |
|
secure I/O paths, secure |
An on-flash counter (per-LEB |
Trigger a key rotation; the new write-active key resets the counters. |
|
secure LEB write |
The supplied payload is larger than the secure LEB capacity (LEB size minus AEAD overhead, or chunk size when chunked layout is enabled) |
Reduce the write size or enable / re-tune |
|
secure read paths, secure attach, reserved-PEB scan |
Authentication failure (AEAD tag mismatch, invalid header magic, CRC mismatch on a secure record) |
Treat the affected record as untrusted. The secure backend will route the failure through the event callback ( |
|
secure attach ( |
A freshness / policy callback rejected the attach; or an attempt was made to unmap a LEB on a static volume |
Attach: investigate |
Per-code notes¶
-ENOSPC is overloaded¶
Three distinct conditions surface as -ENOSPC:
No free PEB for a write — call
ubi_device_erase_peb()until it returns-ENOENT(no dirty PEBs left); if writes still fail with-ENOSPCthe partition is full at the physical level.Volume ID watermark exhausted — the device has created
UINT32_MAXvolumes over its lifetime (volume IDs are monotonic and never reused). This is unrecoverable without a full reformat.Per-key budget reached
ROTATE_NOW_PCT(secure mode only) — the secure backend refuses further writes against a key that has reached its hard usage threshold. Provide a new key version viaget_key_idand either bumprequested_write_key_versioninsecure_cfgor re-attach with the rotated allowlist.
-EROFS and self-healing¶
-EROFS does not mean the device is permanently broken. The
maintenance call ubi_device_erase_peb() is intentionally allowed
in read-only mode: after its dirty-PEB cycle it tries to rewrite the
bad reserved bank from the surviving copy. If that succeeds, the
internal read_only_degraded flag clears and the next mutating call
will succeed. See Architecture Guide § Read-Only
Degraded Mode for the full mutation gate.
-EBADMSG is a security event, not a transient I/O error¶
Never treat -EBADMSG as something to retry. It means a record
authentication tag did not validate — either the flash content was
tampered with, or a key version mismatch slipped through. The secure
backend always emits a corresponding UBI_SECURE_EVENT_* to the
application’s event_cb before returning. Use that event (not the
errno) as the trigger for security policy.
-EBUSY means “single handle per partition”¶
UBI enforces one active ubi_device * per flash partition. The
guard is set in ubi_device_init() and released in
ubi_device_deinit(). Tests that rapidly cycle init/deinit can use
ubi_test_partition_guard_reset() (gated by
CONFIG_UBI_TEST_API_ENABLE) to reset the guard between iterations.
Cross-reference¶
API Reference — the per-function Doxygen reference; each function’s
\retvallines list the codes it can actually return.Secure Architecture: Overview § Events and read-only mode — how
-EBADMSG,-EACCES, and the strict-RO policies interact.Secure UBI Workflow § 4.4 — handling
UBI_SECURE_EVENT_*callbacks (the security counterpart to the errno surface).