Troubleshooting FirmaSAT


  1. Why is my XML signature not valid?
  2. Check for empty fields
  3. Was the signature in my XML document made with MD5 or SHA-1?
  4. What does XMLOK do?
  5. How can I check if my file is in UTF-8?
  6. What is a byte order mark (BOM)?
  7. Must I use fully-prefixed element names in versión 3.0 CFDI documents?
  8. Why do I get a "type's content type is empty" error when validating my signed XML?

Why is my XML signature not valid?

If your XML file does not validate, try the following tests:
  1. FirmaSAT XMLOK miarchivo.xml
    
    If this fails, your XML is badly-formed and needs to be edited (but see also ValidateXml and XMLOK in FirmaSAT 5).
  2. FirmaSAT FORMDIGEST miarchivo.xml
    
    a19eac0f6bba02cecbd6a19738a3de48d3685ba2
    
  3. FirmaSAT EXTRACTDIGEST miarchivo.xml
    
    A19EAC0F6BBA02CECBD6A19738A3DE48D3685BA2
    

    If this test fails with an error, your embedded signature (sello field) is corrupted or the certificate (certificado field) is wrong.

  4. Submit your file to the S.A.T. Validador v2 site (for CFDI version 3.0 files, use the Validador v3 site).
    Archivo XML :miarchivo.xml
    ...
    El sello del comprobante es válido
    ...
    Resultado de la Digestión SHA1 :a19eac0f6bba02cecbd6a19738a3de48d3685ba2
    
    2010-12-24: The v2 validador site now shows the SHA-1 digest for documents dated in 2011 and later. You can tell it's SHA-1 because it's 40 characters long.

The message digest results for tests 2, 3 and 4 should all be the same (it does not matter that the letters are in upper-case [A-F] or lower-case [a-f]). If test 1 is OK, and the results of 2, 3 and 4 are the same, and the XML file still fails SAT validation, do a more detailed check on the XML schema - see XMLPad below. If that's OK as well, please send the file to us for further investigation.

Tests 2 and 3 are equivalent to

FirmaSAT VERIFYSIG myfile.xml

but they provide extra clues as to where the problem may be if the VERIFYSIG action fails.

Test 2
re-computes the message digest of the piped-string (cadena) from the relevant fields in the XML file provided. If this matches test 4 then you know you are at least forming the piped-string correctly.
Test 3
extracts the digest from the signature embedded in the XML file (the signature is, in effect, an encrypted form of the message digest). If you can extract anything from this test, you know you have created the RSA signature correctly, perhaps with the wrong input.
Test 4
gives the "official" correct version of the message digest.

Check for empty fields

The XMLOK test looks for missing fields but does not check for fields that are empty (attr="") that should not be. The XMLPad check below should help here.

For example, a blank "codigoPostal" attribute in the "Domicilio" tag of the "Receptor" will cause a validation error on the SAT site. Even though the attribute is optional, if you include it and leave it empty, it can cause an error with the SAT validator.

Another check is to compare the Resultado de la Digestión SHA1 given on the validator site with the piped string created by FirmaSAT.

FirmaSAT PIPESTRING miarchivo.xml
||2.0|A|1|2011-01-01T16:30:00|1|2011|ingreso|Una sola ...

FirmaSAT creates the piped string as per the SAT specifications, omitting any empty fields. But the SAT validator site now seems to include them and leaves "||" in the Cadena Original. For example, putting aduana="" in the InformacionAduanera element will result in this Cadena Original on the SAT validator. Note the two "|" symbols together.

...2010-09-15||1.00|CILINDRO HIDRAULICO|62003.09|62003.09...

The solution is to delete the attribute and its empty value completely from your XML file, for example: <InformacionAduanera ... aduana="" ... >.

2011-06-05: There is a problem on the SAT validator site with missing, optional nodes in a detallista element. See Errors on the SAT validator site.

Was the signature in my XML document made with MD5 or SHA-1?

To find out which message digest algorithm was used to create the signature (sello), use the EXTRACTDIGEST command to get the message digest in hex form. If it is 32 characters long, then MD5 was used. If it is 40 characters long, then SHA-1 was used.

>FirmaSAT EXTRACTDIGEST Muestra_v2_signed2-md5.xml
4CD8ED248D7A02314C50778A37D1522D
<------------32 chars---------->
>FirmaSAT EXTRACTDIGEST Muestra_v2_signed2-sha1.xml
1B6F53FEF6BC63EA817D6ECF6690F24949F570C8
<----------------40 chars-------------->

The equivalent programming functions are SAT_ExtractDigestFromSignature in C, satExtractDigestFromSignature in VB6, and the Sat.ExtractDigestFromSignature method in .NET.

What does XMLOK do?

The XMLOK action validates the XML, meaning in this case merely that the XML is well formed (i.e. it says nothing about the digital signature). Validation of the XML is carried out using a DTD file plus some other checks. This catches almost all problems but will not catch strict element typing issues (like using a letter in a field where a number is required, or leaving a field empty). The content of the Addenda element is ignored completely.

The "validation" carried out by the SAT Validador sites (CFD versión 2.0 and CFDI versión 3.0) is both a validation of the XML and a verification of the signature.

XMLPad

To carry out a more accurate validation using the XSD file provided by SAT, you will need to use a dedicated XML validation tool. We use WMHelp.com's free XMLPad 3. Use its XML > Validate command.

XMLPad example

XMLPad3 can be frustrating to use. It tries to alter your original file, it sometimes just locks up, and there is no help available. But it's free! When you use XML > Validate, it will go and fetch the required XSD files from the internet, but only if the xsi:schemaLocation attribute is provided in the root Comprobante element.

How can I check if my file is in UTF-8?

Use a tool like hexdump.exe to examine your XML document. Accented characters like áéíóñ should be represented by two bytes in the hex dump.

Here is an extract from an XML document:

pais="México" formaDePago="Una sola exhibición"

Use the command-line instruction

hexdump -C myfile.xml

If your file is in UTF-8 encoding, the accented characters will show as two bytes.

000000  70 61 69 73 3d 22 4d c3 a9 78 69 63 6f 22 20 66  pais="M..xico" f
000010  6f 72 6d 61 44 65 50 61 67 6f 3d 22 55 6e 61 20  ormaDePago="Una
000020  73 6f 6c 61 20 65 78 68 69 62 69 63 69 c3 b3 6e  sola exhibici..n
000030  22                                               "
But if it's in Latin-1 (ISO-8859-1), the accented characters will only show as single byte values.
000000  70 61 69 73 3d 22 4d e9 78 69 63 6f 22 20 66 6f  pais="M.xico" fo
000010  72 6d 61 44 65 50 61 67 6f 3d 22 55 6e 61 20 73  rmaDePago="Una s
000020  6f 6c 61 20 65 78 68 69 62 69 63 69 f3 6e 22     ola exhibici.n"
In this case, you must re-save the file in UTF-8.

You could also use the CNV_CheckUTF8Bytes function or Cnv.CheckUTF8 Method in CryptoSys PKI, reading the file into a byte array first. If the result is zero it means your file is not valid UTF-8.

What is a byte order mark (BOM)?

A byte-order mark for UTF-8 is the sequence of three bytes (0xEF,0xBB,0xBF) at the beginning of a file.

It is generally unnecessary to use a BOM for a UTF-8 file but as of 12 July 2011 the SAT validator sites now seem to require it in all XML documents and will give an error if it is not present. For more on this see UTF-8 byte-order mark problem. We have added a new function in FirmaSAT 4.1 to fix it.

You cannot detect the presence of a BOM using a modern text editor like NotePad or UltraEdit because they look for it and act on it but do not show it (because it actually represents a zero-width, no-break character in Unicode). Older editors may show it as .

You can use a tool like hexdump.exe to examine your XML document or use a hex editor like Frhed Free Hex Editor. The output should look like this:

hexdump -C miarchivo.xml
000000  ef bb bf 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e  ...<?xml version
000010  3d 22 31 2e 30 22 20 65 6e 63 6f 64 69 6e 67 3d  ="1.0" encoding=
000020  22 55 54 46 2d 38 22 3f 3e 0d 0a 3c 43 6f 6d 70  "UTF-8"?>..<Comp
000030  72 6f 62 61 6e 74 65 20 78 6d 6c 6e 73 3d 22 68  robante xmlns="h
000040  74 74 70 3a 2f 2f 77 77 77 2e 73 61 74 2e 67 6f  ttp://www.sat.go

If you see ef bb bf at the beginning then the file has the required BOM.

Must I use fully-prefixed element names in versión 3.0 CFDI documents?

July 2011: This is now fixed in FirmaSAT 4.

You must provide the full prefix for all element names in versión 3.0 CFDI XML documents, e.g. <cfdi:Comprobante> not <Comprobante>, even though it is strictly valid XML to declare this implicitly using the default xmlns namespace.

OK, full prefixes provided for all elements:
<cfdi:Comprobante version="3.0"
 xmlns:cfdi="http://www.sat.gob.mx/cfd/3" ...>
...
  <cfdi:Complemento 
    xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital">
    <tfd:TimbreFiscalDigital ... />
  </cfdi:Complemento>
</cfdi:Combrobante>
Strictly valid XML, but not currently accepted by FirmaSAT:
<Comprobante version="3.0"
 xmlns="http://www.sat.gob.mx/cfd/3" ...>
...
  <Complemento 
    xmlns="http://www.sat.gob.mx/TimbreFiscalDigital">
    <TimbreFiscalDigital ... />
  </Complemento>
</Combrobante>

You still need to provide the fully-qualified names if using the SignXML function on a versión 3.0 CFDi document.

Why do I get a "type's content type is empty" error when validating my signed XML?

This error is not caused by FirmaSAT, but by subsequent processing. See the page "Error: type's content type is empty" when validating XML document signed by FirmaSAT.

Contact us

Contact: Send us a message.

This page last updated 5 May 2012