Gateway Error Code Reference

Look up what each stable GW error code means, the action to take, and the retry strategy Gateway returns.

Every Gateway error response includes a stable code. Find that code below to see what went wrong, what to do next, and the retry strategy Gateway returns in retry.strategy.

If you have not built your error handling yet, start with Handle Gateway error responses. It shows how to confirm that a response is a Gateway error, how to act on each retry strategy, and which documented exceptions override the returned strategy.

Each table has these columns:

  • Meaning and required action: what went wrong and what to do next. When the action says to contact Duplo Support, include the details listed in Contact Duplo Support.
  • Retry strategy: the retry.strategy value Gateway returns. See Choose a retry action for what each value requires. "same key" means the response sets retry.sameIdempotencyKey to true; it applies only to requests that send an idempotency key.

Request, protocol, and routing

CodeHTTPMeaning and required actionRetry strategy
GW_REQUEST_INVALID_JSON400The request body could not be parsed as JSON. Action: Correct the JSON syntax and submit the request again.AFTER_CORRECTION
GW_REQUEST_BODY_INCOMPLETE400Gateway did not receive the complete request body. Action: Send the complete, unchanged request again, keeping the same idempotency key for a mutation.AFTER_CORRECTION; same key
GW_REQUEST_VALIDATION_FAILED400One or more request values are invalid. Action: Correct the values listed in errors and submit the request again.AFTER_CORRECTION
GW_REQUEST_PATH_PARAMETER_INVALID400A path parameter does not match its documented format. Action: Correct the path parameter and submit the request again.AFTER_CORRECTION
GW_REQUEST_HEADER_INVALID400A request header does not match its documented format. Action: Correct the request header and submit the request again.AFTER_CORRECTION
GW_REQUEST_SERVER_FIELD_SUPPLIED400The request contains a field that Gateway sets itself. Action: Remove the server-managed field and submit the request again.AFTER_CORRECTION
GW_REQUEST_BODY_TOO_LARGE413The request body exceeds the endpoint limit. Action: Reduce the request body below the documented limit. Do not split one NRS invoice into several.AFTER_CORRECTION
GW_REQUEST_URI_TOO_LONG414The request path or query exceeds the supported limit. Action: Shorten the request path or query and try again.AFTER_CORRECTION
GW_REQUEST_MEDIA_TYPE_UNSUPPORTED415The request content type is not supported by this endpoint. Action: Send Content-Type: application/json for a JSON body, or the content type documented for the endpoint.AFTER_CORRECTION
GW_ROUTE_NOT_FOUND404The requested method and path do not identify a public endpoint. Action: Use an endpoint listed in Supported NRS endpoints or the API reference.DO_NOT_RETRY
GW_METHOD_NOT_ALLOWED405The endpoint does not support the requested HTTP method. Action: Use a method listed in the Allow response header and API documentation.AFTER_CORRECTION
GW_RATE_LIMIT_EXCEEDED429The request rate is above the permitted limit. Action: Wait for the Retry-After interval, or retry.afterSeconds when no header is present, before trying again.BACKOFF; same key
GW_REQUEST_BODY_TIMEOUT408Gateway did not receive the complete request body before its read deadline. Action: Send the complete, unchanged request again promptly, keeping the same idempotency key for a mutation.SAME_IDEMPOTENCY_KEY; same key
GW_GATEWAY_CAPACITY_EXCEEDED503Gateway is at capacity and cannot safely start another operation right now. Action: Wait for the Retry-After interval, then retry with backoff, keeping the same idempotency key and request content for a mutation.BACKOFF; same key
GW_ROUTING_LOOP_DETECTED508A request that Gateway sent onward was routed back to Gateway. Action: Do not retry until the route is corrected. Contact Duplo Support with requestId.CONTACT_SUPPORT

Entry point, authentication, and top-level business

CodeHTTPMeaning and required actionRetry strategy
GW_EDGE_VERIFICATION_FAILED403The request did not come through Duplo's public API entry point, for example because it was sent to an address other than your approved hostname. Action: Send the request to your approved Gateway hostname. If you are already using that hostname, contact Duplo Support with requestId.DO_NOT_RETRY
GW_AUTH_API_KEY_REQUIRED401The x-api-key header is missing. Action: Add the x-api-key header and submit the request again.AFTER_CORRECTION
GW_API_KEY_INVALID401The supplied API key could not be authenticated. Action: Create or rotate the API key in Duplo Dashboard, then retry.AFTER_CORRECTION
GW_AUTH_TENANT_FORBIDDEN403The API key does not belong to the top-level business that owns this hostname. Action: Use the API key and hostname of the same top-level business.AFTER_CORRECTION
GW_AUTH_CONTEXT_UNAVAILABLE503Gateway could not verify whether the request is authorized. Action: Retry later, keeping the same idempotency key for a mutation, and contact Duplo Support if the error persists.BACKOFF; same key
GW_ADMIN_AUTHENTICATION_FAILED401Operator-only: administrator authentication could not be established. Action: Use the approved private administrator access path and credential. If you receive this on a customer API call, contact Duplo Support with requestId.DO_NOT_RETRY

Domain, mode, and regulator selection

CodeHTTPMeaning and required actionRetry strategy
GW_DOMAIN_NOT_PROVISIONED404The requested hostname is not a provisioned approved domain. Action: Verify the hostname or complete the domain request.AFTER_CORRECTION
GW_DOMAIN_REGISTRY_UNAVAILABLE503Gateway could not load a valid configuration for this domain. Action: Retry with backoff and contact Duplo Support if the error persists.BACKOFF; same key
GW_TENANT_AUTHORIZATION_UNAVAILABLE503The authorization service did not return a valid result, so Gateway could not confirm that the request is authorized. Action: Retry with backoff, keeping the same idempotency key for a mutation.BACKOFF; same key
GW_DOMAIN_APPROVAL_STATE_CHANGED409The approved domain's configuration changed after this request was authorized. Action: Refresh or complete domain approval before resubmitting.AFTER_CORRECTION
GW_TENANT_MODE_UNAVAILABLE503Gateway could not determine whether the approved domain uses Pass-through or Stored mode. Action: Retry later and contact Duplo Support if the error persists.BACKOFF; same key
GW_OPERATION_MODE_CONFLICT409The endpoint is not available in the approved domain's mode. Action: Use the endpoints documented for Pass-through or Stored, whichever your domain uses.AFTER_CORRECTION
GW_REGULATOR_UNAVAILABLE503No usable regulator configuration is available for the top-level business. Action: Contact Duplo Support with requestId to verify regulator provisioning.AFTER_CORRECTION
GW_INVOICE_OPERATION_UNAVAILABLE503The configured invoice operation cannot currently be served. The inbound download and acknowledgement routes always return this code while their ownership check is unavailable. Action: Do not call those routes until Duplo announces that they are enabled; to see inbound invoices already saved under your top-level business, use GET /invoices or GET /invoices/{invoiceId} as described in Poll the invoice, or contact Duplo Support with requestId.CONTACT_SUPPORT

Onboarding and NRS verification

CodeHTTPMeaning and required actionRetry strategy
GW_ONBOARDING_NOT_RESUMABLE409The earlier onboarding request for this idempotency key has expired or can no longer be completed. Action: Stop and contact Duplo Support with requestId and the key. Do not start onboarding with a new key until Duplo confirms the earlier request did not onboard the business.DO_NOT_RETRY
GW_NRS_CREDENTIALS_REQUIRED400Required taxpayer nrsCredentials are missing. Action: Resend the same request with every documented nrsCredentials field, keeping the same idempotency key.AFTER_CORRECTION; same key
GW_ATTESTATION_SERVICE_UNAVAILABLE503Gateway could not produce the required signed attestation. Action: Retry with backoff, the same idempotency key, and the same request content.SAME_IDEMPOTENCY_KEY; same key
GW_NRS_VERIFICATION_UNAVAILABLE503The NRS verification integration cannot currently be used. Action: Retry later with the same idempotency key and request content, or contact Duplo Support.BACKOFF; same key
GW_NRS_LOGIN_INVALID422The taxpayer NRS login supplied for onboarding is invalid. Action: Correct or rotate the taxpayer's NRS login credentials.AFTER_CORRECTION
GW_NRS_APPLICATION_NOT_LINKED403Duplo is not linked to the taxpayer as its Access Point Provider in NRS. Action: Link and approve Duplo as the Access Point Provider in the NRS portal.AFTER_CORRECTION
GW_NRS_CREDENTIALS_REJECTED400NRS rejected the supplied taxpayer credentials. Action: Correct the taxpayer credentials and try again.AFTER_CORRECTION
GW_NRS_AUTH_RESPONSE_INVALID502NRS returned an invalid or unexpected authentication response. Action: Retry with backoff, the same idempotency key, and the same request content.SAME_IDEMPOTENCY_KEY; same key
GW_NRS_AUTH_UNAVAILABLE502The NRS authentication request did not complete successfully. Action: Retry with backoff, the same idempotency key, and the same request content.SAME_IDEMPOTENCY_KEY; same key
GW_NRS_ENTITY_NOT_FOUND404NRS does not contain the requested taxpayer entity. Action: Verify or provision the taxpayer entity in NRS.AFTER_CORRECTION
GW_NRS_ENTITY_INACTIVE422The taxpayer entity is inactive in NRS. Action: Activate the taxpayer entity in NRS before trying again.AFTER_CORRECTION
GW_NRS_ENTITY_METADATA_UNSUPPORTED502NRS returned entity details with values that exceed the limits Gateway accepts. Action: Contact Duplo or NRS support with requestId.DO_NOT_RETRY
GW_NRS_ACTIVE_BUSINESS_NOT_FOUND422The taxpayer entity has no active NRS business. Action: Activate or provision an NRS business.AFTER_CORRECTION
GW_NRS_BUSINESS_INACTIVE422The selected NRS business is inactive. Action: Activate the selected NRS business.AFTER_CORRECTION
GW_NRS_BUSINESS_TIN_NOT_FOUND404No NRS business matches the supplied taxpayer identification number. Action: Correct the TIN or provision the business in NRS.AFTER_CORRECTION
GW_NRS_BUSINESS_SELECTION_AMBIGUOUS409More than one active NRS business matches the available identity. Action: Supply a TIN that identifies exactly one business, or resolve the duplicate businesses in NRS.AFTER_CORRECTION
GW_NRS_BUSINESS_METADATA_INVALID502Required NRS business metadata is missing or malformed. Action: Contact Duplo or NRS support with requestId.DO_NOT_RETRY
GW_NRS_IRN_TEMPLATE_MISSING422The selected NRS business has no IRN template. Action: Configure the IRN template in NRS.AFTER_CORRECTION
GW_ONBOARDING_SERVICE_INVALID_RESPONSE503The onboarding service returned an invalid or unexpected response. Action: Retry with the same idempotency key and request content, and contact Duplo Support if the error persists.SAME_IDEMPOTENCY_KEY; same key
GW_CRYPTO_MATERIAL_SERVICE_INVALID_RESPONSE503The QR-material rotation service returned an invalid or unexpected response. Action: Although the response says to retry with the same key, do not retry this rotation automatically. Keep the key and contact Duplo Support to confirm whether the new material was saved.Response: SAME_IDEMPOTENCY_KEY; same key. Follow the QR-material rotation exception instead.

Represented business and invoice identity

CodeHTTPMeaning and required actionRetry strategy
GW_SUB_BUSINESS_ID_REQUIRED400The x-sub-business-id header is missing. Action: Send the represented business's immutable Gateway ID, returned as gatewaySubBusinessId, in x-sub-business-id.AFTER_CORRECTION
GW_SUB_BUSINESS_ID_INVALID400The represented-business ID is empty, in an unexpected format, or outside the supported length. Action: Copy gatewaySubBusinessId exactly as the onboarding, list, or detail response returned it. Do not change its case, trim it, or convert it.AFTER_CORRECTION
GW_SUB_BUSINESS_NOT_FOUND404No approved represented business exists for that ID under your top-level business. Action: Verify the ID or onboard the represented business before trying again.AFTER_CORRECTION
GW_SUB_BUSINESS_FORBIDDEN403The represented business does not belong to the top-level business that owns this API key. Action: Use a represented business onboarded under this top-level business.AFTER_CORRECTION
GW_INVOICE_IRN_INVALID400The invoice IRN is missing or does not match the supported format. Action: Supply a valid IRN built from the represented business's IRN template.AFTER_CORRECTION
GW_INVOICE_IRN_FORBIDDEN403The IRN is not bound to the represented business in x-sub-business-id. Action: Do not resend this request. Use the IRN issued for that represented business, or the represented business that owns the IRN.DO_NOT_RETRY
GW_INVOICE_BUSINESS_MISMATCH400The invoice body business_id does not match the current NRS business ID of the represented business in x-sub-business-id. Action: Send that represented business's current firsBusinessId (the same value as nrsIdentity.nrsBusinessId) as business_id. It can differ from gatewaySubBusinessId after a protected identity migration.AFTER_CORRECTION
GW_INVOICE_SUPPLIER_TIN_MISMATCH400The supplier TIN in the invoice does not match the TIN in the represented business's current stored identity. Action: Correct the invoice supplier TIN.AFTER_CORRECTION
GW_INVOICE_REFERENCE_MISMATCH400The invoice reference is not identical across the request. Action: Make the header, path, and body invoice references identical.AFTER_CORRECTION
GW_INVOICE_TRANSMIT_BODY_NOT_EMPTY400Pass-through POST /api/v1/invoice/transmit/{irn} accepts no fields in the request body. Action: Send an empty JSON object, {}, and try again.AFTER_CORRECTION

Identity reverification and review

These codes come from reverifying and reviewing NRS identity changes.

CodeHTTPMeaning and required actionRetry strategy
GW_IDENTITY_REVIEW_CONFLICT409A different identity change is already waiting for review, or the selected review has already been decided. Action: Read GET /sub-businesses/{gatewaySubBusinessId}/identity-versions before submitting another decision.AFTER_CORRECTION
GW_IDENTITY_PROTECTED_MIGRATION_REQUIRED409The represented business's NRS entity ID, NRS business ID, or TIN changed. The public decision route cannot apply this change. Action: Contact Duplo Support with requestId; an authorized Duplo operator must review the evidence and approve the protected migration. Do not submit invoices or onboard a duplicate represented business while the review is pending.AFTER_CORRECTION; Duplo operator approval required
GW_IDENTITY_REVIEW_NOT_FOUND404No identity review with that ID exists for this represented business. Action: Read GET /sub-businesses/{gatewaySubBusinessId}/identity-versions and check the review ID.AFTER_CORRECTION
GW_IDENTITY_SERVICE_INVALID_RESPONSE502The identity service returned an invalid or unexpected response. Action: Do not repeat the review decision. Contact Duplo Support with requestId.CONTACT_SUPPORT

Idempotency, billing, signing, transmission, and recovery

CodeHTTPMeaning and required actionRetry strategy
GW_IDEMPOTENCY_KEY_REQUIRED400The x-idempotency-key header is missing. Action: Generate one stable key for this logical operation, store it, and send it in x-idempotency-key.AFTER_CORRECTION
GW_IDEMPOTENCY_KEY_INVALID400The idempotency key does not match the documented format. Action: Use a key that follows the idempotency key rules. Gateway did not accept this request, so no earlier attempt holds the invalid key.AFTER_CORRECTION
GW_IDEMPOTENCY_CONTENT_CONFLICT409The idempotency key was previously used with different content. Action: Do not reuse this key for different content, and do not resend in a loop. If you believe the content is identical, contact Duplo Support with requestId and the key; for onboarding and QR-material rotation, see the 409 exception. Use a new key only for a different invoice or operation.DO_NOT_RETRY
GW_ATTEMPT_NUMBER_INVALID400The x-attempt-number header is not a positive integer. Action: Send a positive integer, or omit the header to use 1.AFTER_CORRECTION
GW_BILLING_WALLET_DECLINED402The wallet could not fund or authorize this invoice operation. Action: Fund or configure the wallet of your top-level business before trying again.AFTER_CORRECTION
GW_BILLING_ATTEMPT_CONFLICT409The billing identity (represented business, domain, IRN, and attempt number) conflicts with an existing attempt. Action: Do not resubmit or bypass the existing attempt; contact Duplo Support with requestId.CONTACT_SUPPORT
GW_BILLING_REQUEST_REJECTED422A recognized billing rule rejected the request. Action: Correct the documented billing prerequisite before trying again.AFTER_CORRECTION
GW_BILLING_SERVICE_UNAVAILABLE503Gateway could not confirm whether the signing fee was charged. Action: Retry only with the same idempotency key, attempt number, and identical content.SAME_IDEMPOTENCY_KEY; same key
GW_SIGN_ATTEMPT_ALREADY_PROCESSED409A sign request with this idempotency key and attempt number was already processed. Action: Do not sign again. Check your stored response, then look up the IRN as described in Safe retry behavior. If the outcome is still unclear, contact Duplo Support with requestId.CONTACT_SUPPORT
GW_SIGN_RECOVERY_UNAVAILABLE503Your wallet was charged, but Gateway could not complete the steps that settle the outcome of the charge. Action: Do not resubmit; contact Duplo Support with requestId.CONTACT_SUPPORT
GW_SIGN_REJECTED422NRS rejected signing and the wallet reversal is confirmed. Action: Correct the invoice, then start a new attempt with the next x-attempt-number and a new idempotency key, as described in Design stable idempotency keys.AFTER_CORRECTION
GW_SIGN_REVERSAL_UNCONFIRMED503Signing was rejected, but the wallet reversal is not yet confirmed. Action: Do not resubmit; contact Duplo Support with requestId.CONTACT_SUPPORT
GW_SIGN_OUTCOME_UNCONFIRMED502The NRS result could not be confirmed and signing may have occurred. Action: Do not resubmit or use a new key; follow Reconcile an unconfirmed sign and contact Duplo Support with requestId.CONTACT_SUPPORT
GW_TRANSMIT_ATTEMPT_ALREADY_PROCESSED409A matching transmission is already in progress or has a recorded outcome. Action: Do not transmit again. Keep the returned operationId and include it when you contact Duplo Support to reconcile the original transmission.DO_NOT_RETRY
GW_TRANSMIT_OUTCOME_UNCONFIRMED502The NRS result could not be confirmed, so the invoice may already have been transmitted. Action: Do not transmit again. Keep the operationId and contact Duplo Support with requestId to reconcile the original transmission.CONTACT_SUPPORT
GW_OPERATION_NOT_FOUND404No operation is available for that public identifier. Action: Verify the operation identifier and hostname, then contact Duplo Support if unexpected.AFTER_CORRECTION

Stored invoices and management

CodeHTTPMeaning and required actionRetry strategy
GW_INVOICE_INTAKE_UNAVAILABLE503Gateway could not confirm whether Stored intake accepted the invoice. Action: Retry with the same idempotency key and identical invoice content.SAME_IDEMPOTENCY_KEY; same key
GW_INVOICE_NOT_FOUND404No invoice with that ID exists under your top-level business in the current test or live state. Action: Verify the Duplo invoiceId and hostname.AFTER_CORRECTION
GW_INVOICE_STATE_CONFLICT409The invoice's current status does not permit the requested transition. Action: Read the invoice with GET /invoices/{invoiceId} and follow the status model.AFTER_CORRECTION
GW_INVOICE_NOT_TRANSMITTABLE422A required transmission prerequisite is incomplete. Action: Complete the documented prerequisite before trying again.AFTER_CORRECTION
GW_MANAGEMENT_SERVICE_UNAVAILABLE503The invoice management service could not complete the request. Action: Retry reads with backoff; retry mutations only with the same idempotency key.BACKOFF; same key
GW_UPSTREAM_RESPONSE_INVALID502A service Gateway relies on returned an invalid or unexpected response. Action: Do not resubmit a mutation; contact Duplo Support with requestId.CONTACT_SUPPORT

Upstream service and unexpected failures

CodeHTTPMeaning and required actionRetry strategy
GW_UPSTREAM_TIMEOUT504A service Gateway relies on, such as NRS, did not respond in time. Action: Do not resubmit a mutation, because it may have completed; contact Duplo Support with requestId. Retry a read only when its route documents it as safe to retry.CONTACT_SUPPORT
GW_UPSTREAM_UNAVAILABLE502A service Gateway relies on, such as NRS, could not complete the request. Action: Do not resubmit a mutation; contact Duplo Support with requestId. For a read, follow the retry guidance for its route.CONTACT_SUPPORT
GW_INTERNAL_ERROR500Gateway encountered an unexpected error. Action: Do not resubmit a mutation; contact Duplo Support with requestId.CONTACT_SUPPORT

Where the request failed

The same kind of outage can return different codes, because the safe action depends on how far the request got:

What failedWhat you receive
Loading your approved domain's configuration503 GW_DOMAIN_REGISTRY_UNAVAILABLE. NRS is not called.
Checking that the request is authorized503 GW_TENANT_AUTHORIZATION_UNAVAILABLE. Gateway never falls back to an earlier authorization result, and NRS is not called.
A Duplo management operation, such as a represented-business or Stored invoice request503 GW_MANAGEMENT_SERVICE_UNAVAILABLE. Retry reads with backoff; retry mutations only with the original idempotency key when the strategy allows it.
Billing, before any charge is confirmed503 GW_BILLING_SERVICE_UNAVAILABLE. NRS is not called.
An ordinary NRS read times out504 GW_UPSTREAM_TIMEOUT. Retry only when the route documents the read as safe to retry.
An ordinary NRS request cannot connect, or NRS returns a 5xx502 GW_UPSTREAM_UNAVAILABLE. Follow the retry guidance for that route.
NRS rate-limits a represented-business route429 GW_RATE_LIMIT_EXCEEDED with Retry-After.
NRS rejects Duplo's own credentialsA Gateway-side dependency failure, not a problem with your API key or invoice. Contact Duplo Support if it persists.
NRS may already have signed or transmitted the invoiceGW_SIGN_OUTCOME_UNCONFIRMED or GW_TRANSMIT_OUTCOME_UNCONFIRMED. Never resubmit.
Gateway cannot safely accept more work503 GW_GATEWAY_CAPACITY_EXCEEDED. Honor Retry-After and keep the original idempotency key.

Duplo diagnoses these failures with the Gateway operations runbook.

How is this guide?

On this page