Qoyod
Pricing

Knowledge Base

Error Code 1012: Duplicate or Invalid UUID (Fix Guide)

You build your integration with the Fatoora platform, test sending an e-invoice, and back comes a rejection with a specific code: 1012. This code tells you that the invoice’s UUID is duplicated or invalid, so ZATCA rejects it before it even looks at any other field. This page is a specialist guide to error code 1012 alone, within the Qoyod e-invoicing.

system. The difference between this page and the UUID errors general page is one of angle. The general page explains all five UUID error patterns (duplicate, wrong format, missing field, reuse, and confusing it with the invoice number). Here we focus on code 1012 specifically: when the system issues it, which cases it covers, how to read its message, and how to fix it for good. If you want to understand the UUID field itself (its definition, format, and position in the XML), its reference is the UUID in the e-invoicepage. And for an overview of the rest of the system’s error categories, you will find it in the ZATCA e-invoicing errors.

guide. The target audience here is the developer or technical integration lead building a connection between an accounting system and the Fatoora platform. That is why you will find real JSON examples of ZATCA’s responses, with each case explained as a problem statement followed by a solution. The English technical tokens such as cbc:UUID andvalidationResults stay as they are because they are actual field names in the API.

The three cases of code 1012
The UUID is duplicated or invalid.
1012 cases

UUID duplicated between two invoices

Invalid format (not v4 or wrong length)

Reusing a UUID on resubmission

The whole document is rejected on the error

A new, non-repeating unique identifier for every invoice.

What error code 1012 means exactly

Code 1012 is not a passing formatting glitch but a final rejection decision. ZATCA issues it when the UUID value fails validation, whether because it is duplicated or because it does not match the required format. The UUID field is mandatory on every e-invoice in Phase Two, and it is a globally unique fingerprint that distinguishes each invoice document from any other invoice in any system in the world.

ZATCA relies on this field to distinguish the document during clearance and reporting, and to prevent invoice duplication in its records. Because the field is mandatory and format-restricted, it accepts no half-measures. The value is either present, correctly formatted, and unique, or code 1012 is issued and the invoice is rejected. There is no “warning” state here, but a direct rejection that puts status on ERROR.

The practical takeaway is that code 1012 gathers under its umbrella two families of problems: duplication and format corruption. Both trace back to the identifier-generation logic in your system, not to the invoice itself. That is why fixing code 1012 always starts from the question: when and how does my system generate the UUID value?

Before we get into the three cases, one essential point deserves clarifying. Most new integration developers treat the UUID as if it were an ordinary serial number, and so they fall into code 1012 without realizing it. But a UUID is not a number you choose or increment by one on each invoice; it is a random value generated by a specific standard to be globally unique with no coordination between systems. Understanding this difference alone prevents most code 1012 cases, because their root is treating the random identifier as a serial number.

The timing of generating the value is no less important than the way it is generated. The value must be generated at the moment each invoice document is created, not before and not after. Generating it early (when preparing a template, for example) opens the door to duplication, and delaying it may produce an empty field that breaks the format. The correct time to generate is the point of creating the document itself, once per document. Keep this rule in mind as you read the three cases, for it is the thread that ties them all together.

Case one: UUID duplicated between two invoices

This is the most common of the code 1012 cases. It happens when your system sends the same value for two different documents, so ZATCA rejects the second because it has already recorded the value for the first. The response message comes in this form:

{
  "validationResults": {
    "status": "ERROR",
    "errorMessages": [
      {
        "type": "ERROR",
        "code": "1012",
        "category": "DUPLICATE_DOCUMENT",
        "message": "Invoice UUID already exists for this taxpayer"
      }
    ],
    "warningMessages": []
  }
}

Root cause. Your system generates the same value for two documents. The most common cause is generating the UUID once and storing it fixed in a template, or copying an old invoice along with its identifier instead of generating a new one, or a flaw in the random-number generator that makes it repeat values.

The solution. Generate a new UUID value at the moment each invoice is created. Do not derive the value from the invoice number, the date, or any repeatable data. Store every generated identifier in a table, and verify before sending that it has not been used before in your system.

To verify the root of the problem in practice, examine when your code calls the generation function. If you find it called on template load or at the start of a user session, that is the flaw, because the value is generated once and reused on every invoice. Move the call inside the invoice-creation function itself, so that each document is matched by an independent generation call. Also add a unique constraint on the identifier column in your database, and this constraint will stop you from saving a duplicate identifier before it even reaches ZATCA.

Case two: invalid UUID format

The second face of code 1012 is format corruption. Even if the value is completely unique, it is rejected if it does not match the standard format of the unique identifier. The required format is a version-four identifier (UUID v4) made up of 36 characters: 32 hexadecimal digits distributed across five groups separated by four hyphens, in the form 8-4-4-4-12.

{
  "validationResults": {
    "status": "ERROR",
    "errorMessages": [
      {
        "type": "ERROR",
        "code": "1012",
        "category": "INVALID_FORMAT",
        "message": "UUID value is not a valid v4 identifier"
      }
    ],
    "warningMessages": []
  }
}

Root cause. The format breaks for several reasons. The length may be wrong (the number of characters is not 36, or the hyphens are out of place), or the value may contain characters outside the hexadecimal system, or your system may generate an identifier of a version other than four, or spaces or hidden characters may be inserted around the value when building it into the XML.

The solution. Use a standard version-four UUID generation function available in your programming language, and do not build the value by hand through string concatenation. Avoid any later transformation that changes the case of the characters or adds a prefix or suffix. Before inserting the value into cbc:UUID, validate it with a regular expression that confirms it matches the format 8-4-4-4-12. And note that code 1012 sometimes does not distinguish in its message between one cause and another, so check the length, the characters, and the version together before you resend.

The correct UUID v4 structure
How the unique identifier is composed and where it goes wrong.
UUID format

36 slots in the 8-4-4-4-12 format

Version 4 in its correct position

Hexadecimal characters only (no spaces)

No repetition across invoices

Make sure a valid UUID v4 is generated for every invoice.

Case three: reusing a UUID on resubmission

This case is more hidden, and it confuses new developers a great deal. When an invoice is rejected for another reason (an error in a tax field, for example), the user fixes it and resubmits it. If you resubmit with the same UUID, ZATCA has already recorded your first attempt with that value, so code 1012 comes back to you as a duplicate value.

Root cause. The system links the UUID to the invoice as a fixed piece of data, so it assumes “the same invoice” must carry the same identifier on every attempt. This is a wrong understanding. The UUID belongs to the submission document, not to the invoice as a business concept. Every submission attempt is a new document from ZATCA’s point of view, and it must carry a new identifier.

The solution. Generate a new UUID on every submission attempt, even if the invoice is the same one that was rejected a moment ago. In your mind, separate the commercial invoice number (which may stay fixed) from the document’s UUID (which changes with every attempt). Design the resubmission logic so that it calls the generation function anew within the correction path, rather than reusing the value stored from the failed attempt.

The golden rule here is simple: do not treat code 1012 as “an error in the old invoice,” but as a signal that the identifier value has been consumed and is no longer usable. Any identifier that reached ZATCA’s record, whether it succeeded or failed, is considered consumed.

This case grows more complicated in systems that store the UUID early within the invoice record and then call it up on every submission. If the first attempt fails and the system keeps the stored value as is, the second attempt sends the same value and code 1012 is issued. The design solution is to not store the UUID value as permanent data in the invoice record, but to generate it within the step of building the submission payload itself. This way every submission is independent by nature, and your team does not need to remember to update the value manually.

Also pay attention to automatic retry operations. Some systems automatically resend the request when the network drops or the timeout expires, so they send the same value twice. If the first attempt actually reached ZATCA and then the response was cut off from you, retrying with the same value produces code 1012 even though the first invoice succeeded. Design the retry logic so that it first queries the document’s status before resending it, or generates a new identifier for each network attempt.

How to read the code 1012 message and diagnose it step by step

When code 1012 reaches you, follow a fixed diagnostic sequence instead of guessing. The goal is to determine which of the three cases you are in before you write any fix.

First, read the category field in the response. A value of DUPLICATE_DOCUMENT means the value is duplicated or reused, and a value of INVALID_FORMAT means the format is corrupt. This field alone splits the problem in two and saves you half the diagnosis time.

Second, extract the UUID value you actually sent from the XML payload. Do not rely on what you think the value is, but on what literally came out of your system. Copy it and check its length and format with a UUID validation tool. If it does not match the standard format, you are in case two.

Third, if the format is sound and the category is DUPLICATE_DOCUMENT, then search for the value itself in the identifier log your system keeps. If you find it linked to a previous successful invoice, you are in case one (a true duplicate). And if you find it linked to a previous failed submission attempt for the same invoice, you are in case three (reuse on resubmission).

Fourth, fix the logic, not the single document. Code 1012 recurs in one batch across all invoices affected by the same flaw. Fixing a single invoice does not solve the root. Modify the generation function, retest it in the sandbox environment, then resend the entire batch with sound identifiers.

It helps you to log, for every submission attempt, the UUID value that actually went out, along with the timestamp and the response status. This log turns diagnosing code 1012 from guesswork into a direct review: you open the log, search for the rejected value, and see when it was first sent and with what status. The log itself reveals recurring flaw patterns, such as a template that returns the same value or a retry path that generates silent duplication.

And finally, beware of the “fix” that looks fast and adds to the problem: manually generating a random value to bypass the rejection on the spot. This hides the root and leaves the broken generation function producing code 1012 in the next batch. Treat the cause once instead of putting out the fire invoice by invoice.

Start today

Let Qoyod handle identifier generation on your behalf

From generating a unique UUID for each document to generating Phase Two-compliant XML, Qoyod manages the entire UUID logic, so code 1012 never reaches you in the first place.

Start your free trial and send your invoices with sound identifiers

How Qoyod helps you avoid code 1012

The core idea is that most code 1012 cases arise from generation logic the integration team writes itself. When an integrated accounting system takes over generating the UUID on your behalf, this category of errors disappears because it leaves the user no opportunity to err in generation in the first place.

Qoyod generates a unique UUID value for every invoice document at the moment of its creation, in the standard version-four format. And because the platform is connected directly to the Fatoora platform, it builds the Phase Two-compliant XML payload and places the identifier in its correct position inside cbc:UUID with no manual intervention. Qoyod also manages the Cryptographic Stamp Identifier (CSID) for each establishment automatically within the e-invoicing system, so it handles the technical side instead of it being a burden on your team.

When a corrected invoice is resubmitted, Qoyod generates a new identifier automatically instead of reusing the old one, so case three is eliminated at its root. The result is that the accountant focuses on the correctness of the tax data, while the platform takes care of the technical details that produce code 1012.

This difference shows clearly in establishments that issue many invoices daily. The higher the invoice volume, the greater the chance that manually written generation logic produces a duplicated or format-corrupt value under pressure. When a system tested on millions of invoices takes over this task, code 1012 becomes a rare event instead of a daily obstacle the integration team chases. The integrated system also provides a unified log of every submission, so you review any previous rejection without building your own diagnostic tools.

Learn about the Qoyod e-invoicing system and its Phase Two requirements, to understand where identifier generation falls within the cycle of issuing a compliant invoice.

Diagnosing code 1012
Three steps to determine the cause of the identifier error.
1

Read category

2

Wrong format: fix v4

3

Duplicate: generate a new identifier

Distinguish a true duplicate from resubmission with an old identifier.

When code 1012 appears in testing and when in production

The severity of code 1012 differs by the environment it appears in. In the sandbox environment, its appearance is useful because it exposes the generation flaw early, before it touches real invoices. Treat any code 1012 in testing as an alarm bell that deserves a root fix immediately, not a bypass with a temporary manual value.

In production, however, the appearance of code 1012 is more dangerous because it means actual rejected invoices that delay reporting. Here the value of the database’s unique constraint shows: if it is present, the duplicate is thwarted in your system before it reaches ZATCA, so it does not turn into a production rejection. Make testing the generation logic a fixed part of the deployment pipeline, so that no change in the invoicing code reaches production without passing a test that generates thousands of identifiers and verifies their uniqueness and format.

The practical rule: treat code 1012 in testing by fixing the code, and in production by stopping the affected batch immediately, fixing the root, then resending with new identifiers. Do not mix the two solutions.

A practical prevention checklist for code 1012

Prevention is cheaper than cure. Review the following points in your code before you launch your integration into production, as they cover the three root causes of code 1012.

Calling generation in the right place. Make sure the identifier-generation function is called inside the submission-payload-building logic, not on template load and not when opening the invoice screen. Each document is matched by one independent call.

A standard version-four generator. Rely on a ready-made function in your language’s library that generates a UUID v4, and do not build the value by string concatenation or with manual random numbers. Standard generators guarantee both the format and the randomness.

Validate the format before sending. Add a validation step with a regular expression that confirms the value is 36 characters in the form 8-4-4-4-12, with no spaces or hidden characters around it. Stop the submission locally if validation fails, as this is cheaper than a rejection from ZATCA.

A unique constraint in the database. Place a unique constraint on the UUID column. This constraint is your last line of defense against duplication before the identifier leaves your system.

A new identifier for every submission attempt. Make the resubmission and automatic-retry path generate a new value, or query the document’s status before reusing a previous value.

A batch test before deployment. Write a test that generates thousands of identifiers at once and verifies their uniqueness and format. Include it in the deployment pipeline so that no change in the invoicing code reaches production without passing it.

From fixing the invoice to fixing the generation logic

The biggest mistake in dealing with code 1012 is treating it invoice by invoice. Because its root is in the generation logic, the single invoice you fixed by hand will come back tomorrow in another invoice as long as the code has not changed. Consider every appearance of code 1012 a signal of a defect in the function that generates the identifier or in the timing of its call, not a defect in the document.

The root fix is threefold: generate the identifier inside the document-creation function once per document, use a standard version-four generator rather than a manual build, and add a unique constraint at the database level. These three layers together close the three doors through which code 1012 enters: duplication, format corruption, and reuse.

Once you install these layers and test them, code 1012 turns from a recurring error that chases you into a rare case you catch before it reaches ZATCA. And most importantly, your fix holds up as invoice volume grows, because it treats the generation logic and not the symptoms. If you want to avoid writing this logic from scratch, adopting an accounting system that handles identifier generation, format, and uniqueness puts these three layers in place by default, so you start from a point free of code 1012.

Frequently asked questions

What is the difference between code 1012 and other UUID errors?

Code 1012 relates specifically to a duplicated or wrong-format unique identifier. Other UUID errors, such as an entirely missing field or confusing it with the invoice number, may be issued under different codes or categories. For a full board of all UUID patterns, see the UUID errors.

Is generating a new UUID enough to fix code 1012?

Generating a new, sound value fixes the current invoice, but it does not fix the root if your system duplicates values or generates them in a wrong format. Fix the generation function and the timing of its call, then add a unique constraint in the database so the error does not recur.

Should I change the invoice number when I change the unique identifier?

No. The commercial invoice number and the document’s UUID are two separate fields. The invoice number may stay fixed on resubmission, while the UUID must change with every submission attempt.

Why does code 1012 come back when resubmitting an invoice that was previously rejected?

Because ZATCA recorded the identifier value from your first attempt, so it has become consumed. Any identifier that reached ZATCA’s record is no longer usable. Generate a new identifier for every submission attempt.

What is the correct format of the unique identifier that the system accepts?

A version-four identifier (UUID v4) made up of 36 characters: 32 hexadecimal digits across five groups in the form 8-4-4-4-12 separated by four hyphens, with no spaces or extra characters around it.

How do I avoid code 1012 without writing generation logic myself?

Use an integrated accounting system that generates the unique identifier and builds the compliant XML on your behalf. Qoyod manages identifier generation, its format, and its uniqueness automatically, so code 1012 never reaches you in the first place.

Guides

Continue your learning journey

Explore the rest of Qoyod’s guides, or start applying what you’ve learned.

Live webinars hosted by the Qoyod team to help you use the software easily and answer your questions.

Discover Qoyod’s latest updates, ongoing improvements, and new features in one place.

Our team is ready to help you and provide instant support for any issue you face, around the clock.