## 2.6. Errors

Vulkan is a layered API. The lowest layer is the core Vulkan layer, as defined by this Specification. The application can use additional layers above the core for debugging, validation, and other purposes.

One of the core principles of Vulkan is that building and submitting command buffers should be highly efficient. Thus error checking and validation of state in the core layer is minimal, although more rigorous validation can be enabled through the use of layers.

The core layer assumes applications are using the API correctly. Except as documented elsewhere in the Specification, the behavior of the core layer to an application using the API incorrectly is undefined, and may include program termination. However, implementations must ensure that incorrect usage by an application does not affect the integrity of the operating system, the Vulkan implementation, or other Vulkan client applications in the system, and does not allow one application to access data belonging to another application. Applications can request stronger robustness guarantees by enabling the `robustBufferAccess` feature as described in Chapter 31, Features, Limits, and Formats.

Validation of correct API usage is left to validation layers. Applications should be developed with validation layers enabled, to help catch and eliminate errors. Once validated, released applications should not enable validation layers by default.

### 2.6.1. Valid Usage

Valid usage defines a set of conditions which must be met in order to achieve well-defined run-time behavior in an application. These conditions depend only on Vulkan state, and the parameters or objects whose usage is constrained by the condition.

Some valid usage conditions have dependencies on run-time limits or feature availability. It is possible to validate these conditions against Vulkan’s minimum supported values for these limits and features, or some subset of other known values.

Valid usage conditions do not cover conditions where well-defined behavior (including returning an error code) exists.

Valid usage conditions should apply to the command or structure where complete information about the condition would be known during execution of an application. This is such that a validation layer or linter can be written directly against these statements at the point they are specified.

| Note
This does lead to some non-obvious places for valid usage statements. For instance, the valid values for a structure might depend on a separate value in the calling command. In this case, the structure itself will not reference this valid usage as it is impossible to determine validity from the structure that it is invalid - instead this valid usage would be attached to the calling command. Another example is draw state - the state setters are independent, and can cause a legitimately invalid state configuration between draw calls; so the valid usage statements are attached to the place where all state needs to be valid - at the draw command.

Certain usage rules apply to all commands in the API unless explicitly denoted differently for a command. These rules are as follows.

#### Valid Usage for Object Handles

Any input parameter to a command that is an object handle must be a valid object handle, unless otherwise specified. An object handle is valid if:

- It has been created or allocated by a previous, successful call to the API. Such calls are noted in the specification.
- It has not been deleted or freed by a previous call to the API. Such calls are noted in the specification.
- Any objects used by that object, either as part of creation or execution, must also be valid.

The reserved handle `VK_NULL_HANDLE` can be passed in place of valid object handles when explicitly called out in the specification. Any command that creates an object successfully must not return `VK_NULL_HANDLE`. It is valid to pass `VK_NULL_HANDLE` to any `vkDestroy*` or `vkFree*` command, which will silently ignore these values.

#### Valid Usage for Pointers

Any parameter that is a pointer must be a valid pointer. A pointer is valid if it points at memory containing values of the number and type(s) expected by the command, and all fundamental types accessed through the pointer (e.g. as elements of an array or as members of a structure) satisfy the alignment requirements of the host processor.

#### Valid Usage for Enumerated Types

Any parameter of an enumerated type must be a valid enumerant for that type. A enumerant is valid if:

- The enumerant is defined as part of the enumerated type.
- The enumerant is not one of the special values defined for the enumerated type, which are suffixed with `_BEGIN_RANGE`, `_END_RANGE`, `_RANGE_SIZE` or `_MAX_ENUM`.

#### Valid Usage for Flags

A collection of flags is represented by a bitmask using the type `VkFlags`:

    typedef uint32_t VkFlags;

Bitmasks are passed to many commands and structures to compactly represent options, but `VkFlags` is not used directly in the API. Instead, a `Vk*Flags` type which is an alias of `VkFlags`, and whose name matches the corresponding `Vk*FlagBits` that are valid for that type, is used. These aliases are described in the Flag Types appendix of the Specification.

Any `Vk*Flags` member or parameter used in the API must be a valid combination of bit flags. A valid combination is either zero or the bitwise OR of valid bit flags. A bit flag is valid if:

- The bit flag is defined as part of the `Vk*FlagBits` type, where the bits type is obtained by taking the flag type and replacing the trailing `Flags` with `FlagBits`. For example, a flag value of type `VkColorComponentFlags` must contain only bit flags defined by `VkColorComponentFlagBits`.
- The flag is allowed in the context in which it is being used. For example, in some cases, certain bit flags or combinations of bit flags are mutually exclusive.

#### Valid Usage for Structure Types

Any parameter that is a structure containing a `sType` member must have a value of `sType` which is a valid `VkStructureType` value matching the type of the structure. As a general rule, the name of this value is obtained by taking the structure name, stripping the leading `Vk`, prefixing each capital letter with `_`, converting the entire resulting string to upper case, and prefixing it with `VK_STRUCTURE_TYPE_`. For example, structures of type `VkImageCreateInfo` must have a `sType` value of `VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO`.

The values `VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO` and `VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO` are reserved for internal use by the loader, and do not have corresponding Vulkan structures in this specification.

The list of supported structure types is defined in an appendix.

#### Valid Usage for Structure Pointer Chains

Any parameter that is a structure containing a `void`* `pNext` member must have a value of `pNext` that is either `NULL`, or points to a valid structure defined by an extension, containing `sType` and `pNext` members as described in the Vulkan Documentation and Extensions document in the section “Extension Interactions”. If that extension is supported by the implementation, then it must be enabled. Any component of the implementation (the loader, any enabled layers, and drivers) must skip over, without processing (other than reading the `sType` and `pNext` members) any chained structures with `sType` values not defined by extensions supported by that component.

Extension structures are not described in the base Vulkan specification, but either in layered specifications incorporating those extensions, or in separate vendor-provided documents.

#### Valid Usage for Nested Structures

The above rules also apply recursively to members of structures provided as input to a command, either as a direct argument to the command, or themselves a member of another structure.

Specifics on valid usage of each command are covered in their individual sections.

### 2.6.2. Return Codes

While the core Vulkan API is not designed to capture incorrect usage, some circumstances still require return codes. Commands in Vulkan return their status via return codes that are in one of two categories:

- Successful completion codes are returned when a command needs to communicate success or status information. All successful completion codes are non-negative values.
- Run time error codes are returned when a command needs to communicate a failure that could only be detected at run time. All run time error codes are negative values.

All return codes in Vulkan are reported via `VkResult` return values. The possible codes are:

    typedef enum VkResult {
        VK_SUCCESS = 0,
        VK_NOT_READY = 1,
        VK_TIMEOUT = 2,
        VK_EVENT_SET = 3,
        VK_EVENT_RESET = 4,
        VK_INCOMPLETE = 5,
        VK_ERROR_OUT_OF_HOST_MEMORY = -1,
        VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
        VK_ERROR_INITIALIZATION_FAILED = -3,
        VK_ERROR_DEVICE_LOST = -4,
        VK_ERROR_MEMORY_MAP_FAILED = -5,
        VK_ERROR_LAYER_NOT_PRESENT = -6,
        VK_ERROR_EXTENSION_NOT_PRESENT = -7,
        VK_ERROR_FEATURE_NOT_PRESENT = -8,
        VK_ERROR_INCOMPATIBLE_DRIVER = -9,
        VK_ERROR_TOO_MANY_OBJECTS = -10,
        VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
        VK_ERROR_FRAGMENTED_POOL = -12,
        VK_ERROR_SURFACE_LOST_KHR = -1000000000,
        VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
        VK_SUBOPTIMAL_KHR = 1000001003,
        VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
        VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
    } VkResult;

Success codes

- `VK_SUCCESS` Command successfully completed
- `VK_NOT_READY` A fence or query has not yet completed
- `VK_TIMEOUT` A wait operation has not completed in the specified time
- `VK_EVENT_SET` An event is signaled
- `VK_EVENT_RESET` An event is unsignaled
- `VK_INCOMPLETE` A return array was too small for the result
- `VK_SUBOPTIMAL_KHR` A swapchain no longer matches the surface properties exactly, but can still be used to present to the surface successfully.

Error codes

- `VK_ERROR_OUT_OF_HOST_MEMORY` A host memory allocation has failed.
- `VK_ERROR_OUT_OF_DEVICE_MEMORY` A device memory allocation has failed.
- `VK_ERROR_INITIALIZATION_FAILED` Initialization of an object could not be completed for implementation-specific reasons.
- `VK_ERROR_DEVICE_LOST` The logical or physical device has been lost. See Lost Device
- `VK_ERROR_MEMORY_MAP_FAILED` Mapping of a memory object has failed.
- `VK_ERROR_LAYER_NOT_PRESENT` A requested layer is not present or could not be loaded.
- `VK_ERROR_EXTENSION_NOT_PRESENT` A requested extension is not supported.
- `VK_ERROR_FEATURE_NOT_PRESENT` A requested feature is not supported.
- `VK_ERROR_INCOMPATIBLE_DRIVER` The requested version of Vulkan is not supported by the driver or is otherwise incompatible for implementation-specific reasons.
- `VK_ERROR_TOO_MANY_OBJECTS` Too many objects of the type have already been created.
- `VK_ERROR_FORMAT_NOT_SUPPORTED` A requested format is not supported on this device.
- `VK_ERROR_FRAGMENTED_POOL` A requested pool allocation has failed due to fragmentation of the pool’s memory.
- `VK_ERROR_SURFACE_LOST_KHR` A surface is no longer available.
- `VK_ERROR_NATIVE_WINDOW_IN_USE_KHR` The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API.
- `VK_ERROR_OUT_OF_DATE_KHR` A surface has changed in such a way that it is no longer compatible with the swapchain, and further presentation requests using the swapchain will fail. Applications must query the new surface properties and recreate their swapchain if they wish to continue presenting to the surface.
- `VK_ERROR_INCOMPATIBLE_DISPLAY_KHR` The display used by a swapchain does not use the same presentable image layout, or is incompatible in a way that prevents sharing an image.

If a command returns a run time error, it will leave any result pointers unmodified, unless other behavior is explicitly defined in the specification.

Out of memory errors do not damage any currently existing Vulkan objects. Objects that have already been successfully created can still be used by the application.

Performance-critical commands generally do not have return codes. If a run time error occurs in such commands, the implementation will defer reporting the error until a specified point. For commands that record into command buffers (`vkCmd*`) run time errors are reported by `vkEndCommandBuffer`.