error recovery

§Reading the local detection sites

The table names the local detection phase, the Rust owner implementing it, and every current source site that emits or examines the cause. Paths are relative to the library crate; line numbers identify this source distribution. Several sites mean that the same cause can arise in several phases. A helper’s local check is not a claim that its enclosing public request has made no native call. The source sites also identify checks carried through closures, macros and deferred-rejection fields; not every mention is a newly emitted public error.

§Effect and recovery contract

InventoryByteQuota reports that an inventory exceeds the cumulative AttributeReadPlan::maximum_bytes selected by its caller. The quota covers available metadata bytes, including each object’s native class value. Class and detail readers use the remaining allowance and can refuse a size or sum before the parent publishes a row. This local refusal does not change the quota, prove that no native call occurred, or grant permission to replay calls. The diagnostic has no secondary-cause payload. Native errors and existing compound errors retain their own information; preserve the complete returned error and use its owner’s documented cleanup path. The diagnostic does not purge objects, enlarge the allowance or retry the inventory automatically. Native buffer-capacity and arithmetic failures remain distinct from this quota.

A synchronous session that has never attempted object creation can close while other sessions on the same token are active, provided it has no retained call, search or advanced owner and another current local session remains. Closing a creator, an asynchronous session or the last local session retains the stronger coordination required by its possible effects. Token/module drain admissions and poisoned, uncertain or retained session state also use that protected path. The native module still determines the outcome; a local population observation does not establish native exclusivity.

TokenActivityDuringSessionClose describes contention during close admission, not proof that every session on a token must be idle. A completed local close does not leave a token-wide SessionClosePending signal. If its native execution or local publication remains unfinished, its receipt retains that signal before session possession ends. Recovery uses the protected close path and the recorded phase, without replaying an already issued close. The signal stops subsequent admissions; it does not cancel readers already admitted. Preserve the owning session and complete error chain, and use its explicit cleanup API. No automatic retry or native completion is implied by either diagnostic.

A cause value is not an operation state or a completion receipt. It does not transfer a handle, session, buffer, ticket or image, and cloning it grants no authority over those resources. The listed implementation owner must be read together with the public return value that still owns the request:

If contextual authentication fails after OAEP initialization, the authentication error describes that call and its own observed inputs. It does not attest to the integrity of the separate retained OAEP descriptor graph. No Decrypt call or plaintext publication follows this failure; the initialized frame remains owned. The OAEP input check after authentication applies only when authentication succeeds. A caller must not interpret an authentication refusal as an integrity verdict for every other buffer retained by the native operation.

For local resource admission, Busy may allow the caller-selected WaitUntil policy to wait for the original admission request. Preserve its deadline and cancellation. It does not wait for cryptographic execution or repair an uncertain native call. A ResourceLimitExceeded request exceeds the caller’s ceiling; waiting cannot admit it. Unsupported requires another explicitly selected capability or representation; there is no automatic fallback.

The safe default for an unrecognized non-exhaustive variant is to return the whole error to the owner of the workflow, without replay, automatic reset, or destruction of retained native operands. The per-cause entries below refine this contract where the reason identifies a particular recovery barrier.

§Typed handling example

This deliberately makes no recovery call: the workflow owner must decide from the complete error and its retained operation, not from a formatted string.

fn return_to_owner(error: fe11::Error) -> Result<(), fe11::Error> {
    if let fe11::Error::Busy(fe11::BusyReason::NativeExecution(
        fe11::NativeExecutionBusy::RuntimeNativeCompletionUnproven,
    )) = &error {
        // Keep the existing runtime; do not create its successor here.
        return Err(error);
    }
    // Includes compound errors and future non-exhaustive reason variants.
    Err(error)
}

§Capacity requests versus invalid native output

A cause whose name contains Capacity or Length is not a buffer-negotiation request. Only the public operation’s typed buffer-request result and its retained Waiting state authorize the corresponding local resize method. A length rejected after CKR_OK can mean native output corruption: the operation can be Failed and its operands retained, even though a larger allocation would fit that number. Another poll/Init must not be used to recover such output. Semantic length checks after a completed call can instead withhold a result while preserving a completed effect diagnostic. In both cases preserve the complete error and owner; no native replay follows from this local cause. Each concrete cause’s phase distinguishes these cases from pre-dispatch arithmetic or record-reconstruction failures.

Interface inventories use ModuleBuilder::observe_interfaces with explicit descriptor, attempt and name-byte bounds. NativeOutputSize and OutputBufferTooSmall use the native function’s units: interface descriptors for C_GetInterfaceList, bytes for byte-producing functions. A list observation is independent of table selection and contains owned names, standard version prefixes and all flags. Nonstandard table contents remain opaque. No Initialize or Finalize call is issued; loading the trusted native image can run constructors.