Errors — ec2-api — branch 17.0.0
Branch
17.0.0@32740781f605— repository https://opendev.org/openstack/ec2-api (retired; local branchpre-retirement) — analysed on 2026-10-29
1. How an error reaches the client
| Where | Condition | Status | Body | Source |
|---|---|---|---|---|
| EC2KeystoneAuth | no signature / no access key | 400 | EC2 XML, AuthFailure "Signature not provided" / "Access key not provided" | ec2api/api/__init__.py:172, ec2api/api/__init__.py:178 |
| EC2KeystoneAuth | Keystone ec2tokens answers non-200 (bad signature, unknown key, expired, ec2credential disabled → 503…) | Keystone's status | EC2 XML, AuthFailure, message = Keystone's reason phrase (Unauthorized, Not Found…) | ec2api/api/__init__.py:213 |
| EC2KeystoneAuth | 200 without a parsable token | 400 | EC2 XML, AuthFailure "Failure communicating with keystone" | ec2api/api/__init__.py:221 |
| EC2KeystoneAuth | Keystone unreachable (requests exception) | 500 or 400 | FaultWrapper (row below) | ec2api/api/__init__.py:211, ec2api/api/__init__.py:70 |
| Requestify | Timestamp+Expires, missing Action | 400 | webob plain text (400 Bad Request\n\n<explanation>), not EC2 XML | ec2api/api/__init__.py:274, ec2api/api/__init__.py:277 |
| Requestify | timestamp expired or invalid | 403 | webob plain text "Timestamp failed validation." | ec2api/api/__init__.py:262 |
| FaultWrapper | any exception outside the Executor (missing Version, Keystone connection error…) | 400 plain text if the request has no AWSAccessKeyId (SigV4); 500 EC2 XML with code HTTPInternalServerError otherwise | ec2api/api/__init__.py:62, ec2api/api/faults.py:46 | |
| Executor | EC2Exception subclass (§ 3) | code = 400 for all of them, including *.NotFound | EC2 XML, ec2_code or class name, formatted message | ec2api/api/__init__.py:389, ec2api/exception.py:131 |
| Executor | botocore.exceptions.ClientError (S3 calls of RegisterImage) | the S3 response's status (400 if absent) | EC2 XML with the S3 error code and message | ec2api/api/__init__.py:377 |
| Executor | any other exception ("unexpected") | first integer attribute among code, status, status_code, http_status, else 500 | EC2 XML, code = the exception class name (NotFound, Forbidden, OverLimit, Conflict, TypeError, KeyError…), message = "Unknown error occurred." when status ≥ 500, else the exception's message or args | ec2api/api/__init__.py:304 |
Consequences for a rewrite and for clients:
- OpenStack client exceptions leak. An uncaught novaclient
Forbidden(Nova policy), neutronclientNotFound, cinderclientOverLimit… is returned with the OpenStack status (403, 404, 413…) and the Python class name as EC2 code, with the OpenStack message (ec2api/api/__init__.py:320,ec2api/api/__init__.py:346). These codes are not in the AWS catalogue; SDKs treat them as generic errors. novaclient exceptions carrycode(novaclient:novaclient/exceptions.py:95[inferred: local clone, not the pinned version]), neutronclient onesstatus_code(neutronclient:neutronclient/common/exceptions.py:72). - Programming errors are 500 with the Python class name:
TypeError(unknown parameter, numeric tag value),UnboundLocalError(boolean-looking security group description),KeyError,AttributeError. The probes of_rewrite/ec2-actions_17.0.0.jsonreproduce them. - Unexpected errors are logged at ERROR with the stack and the request environment's string values (
ec2api/api/__init__.py:352), which includes the form body and headers [inferred:wsgi.inputis not a string, so the body itself is not logged; theHTTP_AUTHORIZATIONheader is]. RequestIDin the error is the context's request ID (the one generated by EC2KeystoneAuth), except for FaultWrapper errors which generate a new one (ec2api/api/faults.py:67).
2. Validation errors (before the implementation)
| Situation | Code | Message (example) | Source |
|---|---|---|---|
unknown Action | InvalidRequest | The request received was invalid. | ec2api/api/apirequest.py:56 |
| required parameter missing | MissingParameter | The required parameter 'cidr_block' is missing (Python name) | ec2api/api/cloud.py:75 |
| string too long / not a string | ValidationError | …'key_name should not be greater than 255 characters.' (also for non-strings) | ec2api/api/validator.py:27 |
| boolean / integer expected | ValidationError | Expected a boolean value for parameter allow_reassociation | ec2api/api/validator.py:36, ec2api/api/validator.py:43 |
| list expected | InvalidParameterValue | Value (x) for parameter instance_id is invalid. Expected a list here | ec2api/api/validator.py:51 |
| bad EC2 ID or wrong prefix | InvalidParameterValue | Value (vpc-xyz) for parameter vpc_id is invalid. Expected: vpc-... | ec2api/api/validator.py:136 |
| bad IPv4 / CIDR | InvalidParameterValue | …Not a valid IP address / This is not a valid CIDR block. | ec2api/api/validator.py:160, ec2api/api/validator.py:99 |
| VPC or subnet CIDR outside /16–/28 | InvalidVpc.Range / InvalidSubnet.Range | The CIDR '10.0.0.0/8' is invalid. | ec2api/api/validator.py:122, ec2api/api/validator.py:127 |
| filter without name or values | InvalidFilter | The filter is invalid. | ec2api/api/validator.py:180 |
| unknown filter name | InvalidParameterValue | Value (foo) for parameter filter is invalid. invalid filter | ec2api/api/common.py:327 |
| key/value list entry without key or value | InvalidParameterValue | …Expected list of key value dictionaries | ec2api/api/validator.py:188 |
| security group name empty / bad characters | ValidationError | …Specified value for parameter Groupgroup_name is invalid. Content limited to 'allowed'. (literal allowed, not the character set) | ec2api/api/validator.py:197 |
VPN type not ipsec.1 | InvalidParameterValue | Value (<class 'type'>) for parameter type is invalid. Invalid VPN connection type. (the builtin type is formatted, not the value) | ec2api/api/validator.py:225 |
MaxResults < 5 | InvalidParameterValue | Value ( 3 ) for parameter maxResults is invalid. Expecting a value greater than 5. (raised with a message only, so the template is bypassed) | ec2api/api/common.py:391 |
Messages name Python parameters (cidr_block, vpc_id), not wire names (CidrBlock, VpcId), because the validator receives the decoded name (ec2api/api/cloud.py:69).
3. Exception catalogue
All AWS-style exceptions derive from EC2Exception (ec2api/exception.py:124, code = 400). The EC2 code is ec2_code when the class defines it, else the class name (ec2api/api/__init__.py:291). The message is msg_fmt % kwargs, or the message argument given at the raise site; a formatting error logs the exception and falls back to the raw msg_fmt (ec2api/exception.py:49, fatal_exception_format_errors = false). "Raised at" lists the direct exception.X( sites (first six); the *.NotFound classes are also raised generically through ec2api/api/ec2utils.py:222 (get_db_item, get_db_items, describers). The machine-readable list is _rewrite/ec2-actions_17.0.0.json (exceptions).
| Class | EC2 code | HTTP | Message template | Raised at |
|---|---|---|---|---|
AddressLimitExceeded | AddressLimitExceeded | 400 | The maximum number of addresses has been reached. | ec2api/api/address.py:221 |
AuthFailure | AuthFailure | 400 | Not authorized. | ec2api/api/address.py:313, ec2api/api/address.py:326, ec2api/api/address.py:415, ec2api/api/address.py:455, ec2api/api/image.py:655, ec2api/context.py:134 (+1) |
CannotDelete | CannotDelete | 400 | Cannot delete the default VPC security group | ec2api/api/security_group.py:530 |
DependencyViolation | DependencyViolation | 400 | Object %(obj1_id)s has dependent resource %(obj2_id)s | ec2api/api/dhcp_options.py:101, ec2api/api/internet_gateway.py:102, ec2api/api/route_table.py:321, ec2api/api/security_group.py:535, ec2api/api/subnet.py:108, ec2api/api/vpc.py:80 |
EC2DuplicateException | EC2DuplicateException | 400 | (inherited: An unknown exception occurred.) | — |
EC2Exception | EC2Exception | 400 | (inherited: An unknown exception occurred.) | ec2api/api/image.py:150, ec2api/api/image.py:1029, ec2api/api/image.py:1034, ec2api/api/image.py:1044, ec2api/api/image.py:1095, ec2api/db/migration.py:42 (+2) |
EC2InUseException | EC2InUseException | 400 | (inherited: An unknown exception occurred.) | — |
EC2IncorrectStateException | EC2IncorrectStateException | 400 | (inherited: An unknown exception occurred.) | — |
EC2InvalidException | EC2InvalidException | 400 | (inherited: An unknown exception occurred.) | ec2api/api/image.py:1066 |
EC2NotFoundException | EC2NotFoundException | 400 | (inherited: An unknown exception occurred.) | — |
EC2OverlimitException | EC2OverlimitException | 400 | (inherited: An unknown exception occurred.) | — |
GatewayNotAttached | Gateway.NotAttached | 400 | resource %(gw_id)s is not attached to network %(vpc_id)s | ec2api/api/address.py:370, ec2api/api/internet_gateway.py:78, ec2api/api/route_table.py:111 |
IncorrectInstanceState | IncorrectInstanceState | 400 | The instance '%(instance_id)s' is not in a state from which the requested operation can be performed. | ec2api/api/instance.py:678, ec2api/api/instance.py:1067 |
IncorrectState | IncorrectState | 400 | The resource is in incorrect state for the request - reason: '%(reason)s' | ec2api/api/customer_gateway.py:56, ec2api/api/image.py:127, ec2api/api/image.py:316, ec2api/api/image.py:544, ec2api/api/image.py:561, ec2api/api/snapshot.py:43 (+2) |
InsufficientFreeAddressesInSubnet | InsufficientFreeAddressesInSubnet | 400 | The specified subnet does not have enough free addresses to satisfy the request. | ec2api/api/network_interface.py:135, ec2api/api/network_interface.py:296 |
InvalidAMIIDNotFound | InvalidAMIID.NotFound | 400 | The image id '[%(id)s]' does not exist | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP, ec2api/api/ec2utils.py:362, ec2api/api/ec2utils.py:370, ec2api/api/image.py:389 |
InvalidAMIIDUnavailable | InvalidAMIID.Unavailable | 400 | Image %(image_id)s is not active. | ec2api/api/instance.py:885 |
InvalidAddressNotFound | InvalidAddress.NotFound | 400 | The specified elastic IP address %(ip)s cannot be found. | — |
InvalidAllocationIDNotFound | InvalidAllocationID.NotFound | 400 | The allocation ID '%(id)s' does not exist | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP, ec2api/api/address.py:254, ec2api/api/address.py:347 |
InvalidAssociationIDNotFound | InvalidAssociationID.NotFound | 400 | The association ID '%(id)s' does not exist | ec2api/api/address.py:426, ec2api/api/route_table.py:176, ec2api/api/route_table.py:190, ec2api/api/route_table.py:216, ec2api/api/route_table.py:221 |
InvalidAttachmentIDNotFound | InvalidAttachmentID.NotFound | 400 | Attachment %(id)s could not be found. | ec2api/api/network_interface.py:419, ec2api/api/network_interface.py:478 |
InvalidAttribute | InvalidAttribute | 400 | Attribute not supported: %(attr)s | ec2api/api/instance.py:89, ec2api/api/instance.py:92 |
InvalidAvailabilityZoneNotFound | InvalidAvailabilityZone.NotFound | 400 | Availability zone %(id)s not found | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP |
InvalidBlockDeviceMapping | InvalidBlockDeviceMapping | 400 | (inherited: An unknown exception occurred.) | ec2api/api/instance.py:937, ec2api/api/instance.py:978, ec2api/api/instance.py:983, ec2api/api/instance.py:987, ec2api/api/instance.py:996 |
InvalidCustomerGatewayDuplicateIpAddress | InvalidCustomerGateway.DuplicateIpAddress | 400 | Conflict among chosen gateway IP addresses. | ec2api/api/vpn_connection.py:63 |
InvalidCustomerGatewayIDNotFound | InvalidCustomerGatewayID.NotFound | 400 | The customerGateway ID '%(id)s' does not exist | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP |
InvalidDhcpOptionsIDNotFound | InvalidDhcpOptionsID.NotFound | 400 | The dhcp options ID '%(id)s' does not exist | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP |
InvalidFilter | InvalidFilter | 400 | The filter is invalid. | ec2api/api/validator.py:184 |
InvalidGatewayIDNotFound | InvalidGatewayID.NotFound | 400 | The gateway ID '%(id)s' does not exist | ec2api/api/route_table.py:375 |
InvalidGroupDuplicate | InvalidGroup.Duplicate | 400 | Security group '%(name)s' already exists. | ec2api/api/security_group.py:80 |
InvalidGroupNotFound | InvalidGroup.NotFound | 400 | The security group ID '%(id)s' does not exist | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP, ec2api/api/network_interface.py:125, ec2api/api/security_group.py:585 |
InvalidGroupReserved | InvalidGroup.Reserved | 400 | The security group '%(group_name)' is reserved. | ec2api/api/security_group.py:65 |
InvalidID | InvalidID | 400 | The ID '%(id)s' is not valid | ec2api/api/tag.py:71 |
InvalidIPAddressInUse | InvalidIPAddress.InUse | 400 | Address %(ip_address)s is in use. | ec2api/api/address.py:272, ec2api/api/address.py:275 |
InvalidInput | InvalidInput | 400 | Invalid input received: %(reason)s | ec2api/service.py:86, ec2api/wsgi.py:108 |
InvalidInstanceIDNotFound | InvalidInstanceID.NotFound | 400 | The instance ID '%(id)s' does not exist | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP, ec2api/api/instance.py:1088 |
InvalidInstanceId | InvalidInstanceID | 400 | There are multiple interfaces attached to instance '%(instance_id)s'. Please specify an interface ID for the operation instead. | ec2api/api/address.py:337, ec2api/api/instance.py:512, ec2api/api/instance.py:522, ec2api/api/instance.py:649, ec2api/api/instance.py:664, ec2api/api/route_table.py:402 |
InvalidInternetGatewayIDNotFound | InvalidInternetGatewayID.NotFound | 400 | The internetGateway ID '%(id)s' does not exist | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP |
InvalidKeyPairDuplicate | InvalidKeyPair.Duplicate | 400 | Key pair '%(key_name)s' already exists. | ec2api/api/key_pair.py:116, ec2api/api/key_pair.py:134 |
InvalidKeypairNotFound | InvalidKeyPair.NotFound | 400 | Keypair %(id)s is not found | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP |
InvalidNetworkInterfaceIDNotFound | InvalidNetworkInterfaceID.NotFound | 400 | Network interface %(id)s could not be found. | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP |
InvalidNetworkInterfaceInUse | InvalidNetworkInterface.InUse | 400 | Interface: %(interface_ids)s in use. | ec2api/api/instance.py:1395 |
InvalidParameter | InvalidParameter | 400 | The property '%(name)s' is not valid | ec2api/api/availability_zone.py:150, ec2api/api/image.py:600 |
InvalidParameterCombination | InvalidParameterCombination | 400 | The combination of parameters in incorrect | ec2api/api/address.py:62, ec2api/api/address.py:83, ec2api/api/address.py:95, ec2api/api/address.py:309, ec2api/api/address.py:335, ec2api/api/image.py:215 (+26) |
InvalidParameterValue | InvalidParameterValue | 400 | Value (%(value)s) for parameter %(parameter)s is invalid. %(reason)s | ec2api/api/address.py:47, ec2api/api/address.py:243, ec2api/api/address.py:400, ec2api/api/address.py:419, ec2api/api/common.py:329, ec2api/api/common.py:394 (+63) |
InvalidPermissionDuplicate | InvalidPermission.Duplicate | 400 | The specified rule already exists for that security group. | ec2api/api/security_group.py:558 |
InvalidPermissionNotFound | InvalidPermission.NotFound | 400 | (inherited: An unknown exception occurred.) — **msg_fmg typo: real message is the inherited one** | ec2api/api/security_group.py:397 |
InvalidRequest | InvalidRequest | 400 | The request received was invalid. | ec2api/api/apirequest.py:56, ec2api/api/ec2utils.py:190, ec2api/api/image.py:539, ec2api/api/image.py:644, ec2api/api/route_table.py:412 |
InvalidRouteNotFound | InvalidRoute.NotFound | 400 | No route with destination-cidr-block %(destination_cidr_block)s in route table %(route_table_id)s | ec2api/api/route_table.py:82, ec2api/api/vpn_connection.py:139 |
InvalidRouteTableIDNotFound | InvalidRouteTableID.NotFound | 400 | The routeTable ID '%(id)s' does not exist | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP |
InvalidSecurityGroupIDNotFound | InvalidSecurityGroupID.NotFound | 400 | The securityGroup ID '%(id)s' does not exist | — |
InvalidSnapshotIDMalformed | InvalidSnapshotID.Malformed | 400 | (inherited: An unknown exception occurred.) — **msg_fmg typo: real message is the inherited one** | ec2api/api/instance.py:917 |
InvalidSnapshotNotFound | InvalidSnapshot.NotFound | 400 | Snapshot %(id)s could not be found. | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP |
InvalidSubnetConflict | InvalidSubnet.Conflict | 400 | The CIDR '%(cidr_block)s' conflicts with another subnet | ec2api/api/subnet.py:75 |
InvalidSubnetIDNotFound | InvalidSubnetID.NotFound | 400 | The subnet ID '%(id)s' does not exist | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP, ec2api/api/network_interface.py:68 |
InvalidSubnetRange | InvalidSubnet.Range | 400 | The CIDR '%(cidr_block)s' is invalid. | ec2api/api/subnet.py:48, ec2api/api/validator.py:129 |
InvalidVolumeNotFound | InvalidVolume.NotFound | 400 | The volume '%(id)s' does not exist. | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP |
InvalidVpcIDNotFound | InvalidVpcID.NotFound | 400 | The vpc ID '%(id)s' does not exist | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP |
InvalidVpcRange | InvalidVpc.Range | 400 | The CIDR '%(cidr_block)s' is invalid. | ec2api/api/validator.py:124 |
InvalidVpcState | InvalidVpcState | 400 | VPC %(vpc_id)s is currently attached to the Virtual Private Gateway %(vgw_id)s | ec2api/api/vpn_gateway.py:49 |
InvalidVpnConnectionIDNotFound | InvalidVpnConnectionID.NotFound | 400 | The vpnConnection ID '%(id)s' does not exist | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP |
InvalidVpnGatewayAttachmentNotFound | InvalidVpnGatewayAttachment.NotFound | 400 | The attachment with vpn gateway ID '%(vgw_id)s' and vpc ID '%(vpc_id)s' does not exist | ec2api/api/vpn_gateway.py:81 |
InvalidVpnGatewayIDNotFound | InvalidVpnGatewayID.NotFound | 400 | The vpnGateway ID '%(id)s' does not exist | via ec2api/api/ec2utils.py:222 NOT_FOUND_EXCEPTION_MAP |
MissingInput | MissingInput | 400 | (inherited: An unknown exception occurred.) | ec2api/api/instance.py:1313 |
MissingParameter | MissingParameter | 400 | The required parameter '%(param)s' is missing | ec2api/api/address.py:58, ec2api/api/address.py:65, ec2api/api/address.py:79, ec2api/api/address.py:91, ec2api/api/cloud.py:75, ec2api/api/dhcp_options.py:95 (+10) |
OperationNotPermitted | OperationNotPermitted | 400 | The specified operation is not allowed. | ec2api/api/instance.py:197, ec2api/api/network_interface.py:480 |
ResourceAlreadyAssociated | Resource.AlreadyAssociated | 400 | (inherited: An unknown exception occurred.) | ec2api/api/address.py:359, ec2api/api/internet_gateway.py:52, ec2api/api/route_table.py:157 |
ResourceLimitExceeded | ResourceLimitExceeded | 400 | You have reached the limit of %(resource)s | ec2api/api/key_pair.py:114, ec2api/api/key_pair.py:132, ec2api/api/security_group.py:96 |
RouteAlreadyExists | RouteAlreadyExists | 400 | The route identified by %(destination_cidr_block)s already exists. | ec2api/api/route_table.py:428 |
RulesPerSecurityGroupLimitExceeded | RulesPerSecurityGroupLimitExceeded | 400 | You've reached the limit on the number of rules that you can add to a security group. | ec2api/api/security_group.py:556 |
SecurityGroupLimitExceeded | SecurityGroupLimitExceeded | 400 | You have reached the limit of security groups | — |
SubnetLimitExceeded | SubnetLimitExceeded | 400 | You have reached the limit on the number of subnets that you can create | ec2api/api/subnet.py:70 |
Unsupported | Unsupported | 400 | The specified request is unsupported. %(reason)s | ec2api/api/customer_gateway.py:39, ec2api/api/customer_gateway.py:41, ec2api/api/ec2utils.py:474, ec2api/api/instance.py:1457, ec2api/api/instance.py:1461, ec2api/api/vpn_connection.py:49 |
UnsupportedOperation | UnsupportedOperation | 400 | The specified request includes an unsupported operation. | ec2api/api/instance.py:1355, ec2api/api/volume.py:86, ec2api/api/volume.py:124 |
VPCIdNotSpecified | VPCIdNotSpecified | 400 | No default VPC for this user. | ec2api/api/ec2utils.py:499 |
ValidationError | ValidationError | 400 | The input fails to satisfy the constraints specified by an AWS service: '%(reason)s' | ec2api/api/validator.py:31, ec2api/api/validator.py:39, ec2api/api/validator.py:46, ec2api/api/validator.py:221 |
VpcLimitExceeded | VpcLimitExceeded | 400 | The maximum number of VPCs has been reached. | ec2api/api/vpc.py:134 |
VpnGatewayAttachmentLimitExceeded | VpnGatewayAttachmentLimitExceeded | 400 | The maximum number of virtual private gateway attachments has been reached. | ec2api/api/vpn_gateway.py:46 |
EC2APIConfigNotFound | EC2APIConfigNotFound | 500 | Could not find config at %(path)s | ec2api/wsgi.py:498 |
EC2APIException | EC2APIException | 500 | An unknown exception occurred. | ec2api/api/instance.py:698 |
EC2APIPasteAppNotFound | EC2APIPasteAppNotFound | 500 | Could not load paste app '%(name)s' from %(path)s | ec2api/wsgi.py:514 |
EC2DBDuplicateEntry | EC2DBDuplicateEntry | 500 | Entry %(id)s already exists in DB. | ec2api/db/sqlalchemy/api.py:193 |
EC2DBInvalidOsIdUpdate | EC2DBInvalidOsIdUpdate | 500 | Invalid update of os_id of %(item_id)s item from %(old_os_id)s to %(new_os_id)s | ec2api/db/sqlalchemy/api.py:153 |
EC2KeystoneDiscoverFailure | EC2KeystoneDiscoverFailure | 500 | Could not discover keystone versions. | — |
EC2MetadataException | EC2MetadataException | 500 | (inherited: An unknown exception occurred.) | — |
EC2MetadataInvalidAddress | EC2MetadataInvalidAddress | 500 | (inherited: An unknown exception occurred.) | ec2api/metadata/__init__.py:209 |
EC2MetadataNotFound | EC2MetadataNotFound | 500 | (inherited: An unknown exception occurred.) | ec2api/metadata/api.py:79, ec2api/metadata/api.py:88, ec2api/metadata/api.py:100, ec2api/metadata/api.py:147, ec2api/metadata/api.py:164, ec2api/metadata/api.py:305 (+1) |
3.1 Main situations, in business terms
| Code | Situations | Source |
|---|---|---|
<Kind>.NotFound (InvalidInstanceID.NotFound, InvalidVpcID.NotFound, InvalidAMIID.NotFound, InvalidVolume.NotFound…) | the ID is not an item of the caller's project (other projects' items are invisible), or the prefix does not match the expected kind, or a Describe with explicit IDs did not find all of them (the first missing one is reported) | ec2api/api/ec2utils.py:245, ec2api/api/ec2utils.py:267, ec2api/api/common.py:442 |
InvalidInstanceID.NotFound | additionally: the server vanished from Nova during Reboot/Stop/Start (the item is then deleted) | ec2api/api/instance.py:1087 |
InvalidAMIID.NotFound | image ID unmapped, or Glance 404 | ec2api/api/ec2utils.py:358 |
InvalidAMIID.Unavailable | RunInstances on an image that is not available (message "Image must be available") | ec2api/api/instance.py:882 |
IncorrectInstanceState | Reboot/Stop/Start from a disallowed vm_state; resize of a non-stopped instance | ec2api/api/instance.py:1066, ec2api/api/instance.py:675 |
OperationNotPermitted | TerminateInstances with disableApiTermination; DetachNetworkInterface at index 0 | ec2api/api/instance.py:197, ec2api/api/network_interface.py:480 |
InvalidParameterCombination | mutually exclusive parameters (RunInstances network options, ModifyInstanceAttribute, AssociateAddress, MaxResults with IDs…) | ec2api/api/instance.py:1243, ec2api/api/instance.py:610, ec2api/api/address.py:59 |
DependencyViolation | deleting a VPC, subnet, route table, internet gateway, DHCP options or security group still in use (Neutron 409 on a security group) | ec2api/api/vpc.py:80, ec2api/api/subnet.py:108, ec2api/api/route_table.py:321, ec2api/api/security_group.py:535 |
VpcLimitExceeded, SubnetLimitExceeded, AddressLimitExceeded, ResourceLimitExceeded, RulesPerSecurityGroupLimitExceeded, InsufficientFreeAddressesInSubnet | Neutron/Nova quota (OverQuotaClient, OverLimit) or no free IP | ec2api/api/vpc.py:134, ec2api/api/subnet.py:70, ec2api/api/address.py:221, ec2api/api/key_pair.py:114, ec2api/api/security_group.py:556, ec2api/api/network_interface.py:135 |
InvalidSubnet.Conflict | Neutron refuses the router interface (overlapping CIDR) | ec2api/api/subnet.py:75 |
Unsupported | no or several external networks ("Feature is restricted by OS admin"); no or several EC2-Classic networks; BGP VPN; customer gateway without IP | ec2api/api/ec2utils.py:474, ec2api/api/instance.py:1457, ec2api/api/vpn_connection.py:49, ec2api/api/customer_gateway.py:39 |
AuthFailure (inside actions) | image of another project in Deregister/Modify/Describe attribute; elastic IP that is not the caller's | ec2api/api/image.py:655, ec2api/api/address.py:455 |
VPCIdNotSpecified | disable_ec2_classic and the default VPC could not be created | ec2api/api/ec2utils.py:499 |
MissingInput | default VPC without subnet (code MissingInput, message given at the raise site) | ec2api/api/instance.py:1313 |
3.2 Defects in the catalogue (keep or fix deliberately)
InvalidSnapshotIDMalformedandInvalidPermissionNotFounddefinemsg_fmginstead ofmsg_fmt(ec2api/exception.py:252,ec2api/exception.py:391): their message is the base "An unknown exception occurred.".InvalidPermission.NotFoundis what RevokeSecurityGroupIngress/Egress returns for a missing VPC rule (ec2api/api/security_group.py:397).InvalidGroupReservedhas a broken template'%(group_name)'(ec2api/exception.py:494): formatting fails, the error is logged, and the client gets the raw templateThe security group '%(group_name)' is reserved.InvalidParameterValue(msg)and other classes raised with a bare message bypass the template (ec2api/api/common.py:394); raised with keyword arguments but a missing key (InvalidParameterValue(parameter=…, value=…)withoutreason) they fall back to the raw template [inferred fromec2api/exception.py:53].MissingInputhas nomsg_fmt(ec2api/exception.py:197); it is only raised with a message.InvalidAddressNotFound,InvalidSecurityGroupIDNotFound,SecurityGroupLimitExceededare never raised.NOT_FOUND_EXCEPTION_MAPhas no entry foreipassoc,rtbassoc,eni-attach,r,aki/aridescribers useami's class; a lookup of an unmapped kind would raiseKeyError→ 500 (ec2api/api/ec2utils.py:263) [inferred: callers always pass a mapped kind].
4. Errors outside the API
| Where | Situation | What happens | Source |
|---|---|---|---|
| CreateImage (green thread) | stop/snapshot fails, or the server does not reach SHUTOFF within 1 h | item state=failed (DescribeImages shows failed), LOG.exception('Failed to complete image %s creation'); the server is restarted in any case, failures logged at WARNING | ec2api/api/image.py:158, ec2api/api/image.py:168 |
| RegisterImage from S3 (green thread) | download, decrypt (openssl enc -d -aes-128-cbc), untar or upload fails | Glance property image_state = failed_download / failed_decrypt / failed_untar / failed_upload (EC2 state failed), logged; the temporary directory is left behind on failure; an image deleted meanwhile is logged at INFO | ec2api/api/image.py:887, ec2api/api/image.py:949 |
| S3 manifest decryption | x509_root_private_key not set or wrong | EC2Exception "Path to ca private key isn't configured" / "Failed to decrypt private key" → image failed_decrypt | ec2api/api/image.py:1091, ec2api/api/image.py:1027 |
Rollbacks (OnCrashCleaner) | a cleanup step fails | LOG.warning('Error cleaning up <function>(<args>)'), the original error is still returned; OpenStack objects may be left behind | ec2api/api/common.py:63 |
| Default VPC creation | any failure | LOG.exception('Failed to create default vpc'), the call continues as if there were no default VPC | ec2api/api/vpc.py:184 |
| Default security group repair | duplicate item or VPC vanished | LOG.exception('Failed to create default security group.') | ec2api/api/security_group.py:124 |
| VPC/subnet/VPN deletion | Neutron 409 on router, network, vpnservice, IKE/IPsec policy | logged at WARNING, the EC2 deletion still succeeds: Neutron objects can be orphaned | ec2api/api/vpc.py:94, ec2api/api/subnet.py:129, ec2api/api/vpn_gateway.py:199, ec2api/api/vpn_connection.py:166 |
| Metadata service | unknown path/version, instance not found or of another project | 404 (EC2MetadataNotFound); other exceptions 500 "An unknown error has occurred. Please try your request again." | ec2api/metadata/__init__.py:113 |
| Metadata proxy to Nova | Nova metadata answers 403/400/404/409/500 | same status (403 logged as a shared-secret mismatch); other statuses raise → 500 | ec2api/metadata/__init__.py:146 |
| S3 server | any handler exception | 501 with <Error><Code>BadRequest</Code><Message>Unhandled error</Message></Error> | ec2api/s3/s3server.py:150 |
| Database | random ID collision on items.id | DBDuplicateEntry re-raised → 500 DBDuplicateEntry (probability ≈ n/2³² per insert) | ec2api/db/sqlalchemy/api.py:107 |
| Database | concurrent update_item after a delete | NoResultFound → 500 | ec2api/db/sqlalchemy/api.py:148 |
5. Errors observed in the tests
_rewrite/observed-errors-api-tests_17.0.0.md lists the (action, status, code, message) combinations the unit tests produced (227 rows). The 500 Exception rows come from tests that inject a generic exception to check the rollbacks; they are not reachable as such. The metadata and S3 runs are in _rewrite/observed-errors-metadata-tests_17.0.0.md and _rewrite/observed-errors-s3-tests_17.0.0.md.
Source: reverse-spec-ec2-api/02-errors_17.0.0.md. The _rewrite/ and _inventory/ files are not published on the site.