Skip to content

Errors and status codes

Every failure the SDK raises on purpose is a DteError with a stable code. You branch on the code and read the context from details; you never parse the message. This page lists every code, what raises it and what its details usually hold, then covers the SII status codes (upload, reception, document, claims and transferability) that are returned as data rather than thrown.

Using DteError#

TypeScript
import { createDocument, DteError, errorCode, isDteError } from 'dte-sdk'
 
try {
  createDocument({ ...input, items: [{ name: 'x'.repeat(81), unitPrice: 1 }] })
} catch (error) {
  if (isDteError(error)) {
    error.code // 'FIELD_TOO_LONG'
    error.message // 'Field exceeds the maximum length allowed by the SII schema (field=NmbItem, maxLength=80, length=81)'
    error.details // { field: 'NmbItem', maxLength: 80, length: 81, value: 'xxxxxxxx…' }
  }
}
ExportWhat it does
DteErrorThe error class. code is a DteErrorCode, details is a read-only record of context.
isDteError(value)Type guard: true when value is a DteError.
errorCode(value)The code when value is a DteError, else undefined. Handy when you report failures as data.
DTE_ERROR_CODESThe object with every code: DTE_ERROR_CODES.INVALID_RUT === 'INVALID_RUT'.
DteErrorCode, DteErrorDetailsThe types of the code and of the details.
isRetryableError(value)True for the errors worth another attempt. See Retrying.

details versus message#

The message is generic and safe to log: it is a fixed sentence per code, followed by a short list of safe detail keys, that is, field names, codes and numbers. It never includes RUTs, names, item text, URLs or response bodies. The safe keys are field, maxLength, length, type, folio, from, to, kind, index, status, httpStatus, code, attempts, channel, operation, trackId, expected, actual, rejection, step, module, day, listed and covered.

Everything else lives in details only: the offending value, a RUT, a response excerpt (with tokens and seeds redacted), the URL that was called. Treat details as sensitive: do not send it whole to a log or to an error tracker. Pick the keys you need (error.details.field, error.details.status).

TypeScript
logger.error('upload failed', { code: error.code, status: error.details.status }) // fine
logger.error('upload failed', error.details) // may carry RUTs, a response excerpt, the offending value

Error codes#

Codes are grouped by what they are about. "Typical details" are the keys the code usually carries; an operation may add more (every transport error also carries operation).

Input validation#

CodeRaised whenTypical details
INVALID_RUTA RUT is malformed or its check digit is wrong. Raised by every function that takes a RUT.field
INVALID_DOCUMENT_TYPEThe document type is not supported. Also: a type outside 33, 34 and 43 in the claim registry, outside BOOK_DOCUMENT_TYPES in a book, outside 39 and 41 in a folio consumption report, a non-guide in guideEntryFromDocument.field, type, index
INVALID_FOLIOA folio is not a positive integer (books: at most 10 digits). In a folio consumption report, a folio repeated across lines.field, folio, type, index
INVALID_DATEA date is not YYYY-MM-DD, a period is not YYYY-MM, or a book date is outside 2000 to 2050.field
INVALID_AMOUNTAn amount is not a finite number (books: not a safe integer, or negative where the schema forbids it).field, index
MISSING_FIELDA required field or option is absent: for example companyRut in a call with no client default, cover.notificationFolio in a special book.field
FIELD_TOO_LONGA text exceeds the maximum length of the SII schema (for example 80 characters for an item name).field, maxLength, length, value
INVALID_OPTIONAn option has an invalid value: an unknown environment or channel, a non-positive timeout, a bad trackId, a seed that is not digits, a fileName that is not safe, a book zone that does not fit its submission…field, sometimes index
ENCODING_UNSUPPORTED_CHARA text contains a character outside ISO-8859-1, so it cannot be sent or stamped.index, codePoint

CAF and folios#

CodeRaised whenTypical details
CAF_INVALIDThe CAF XML cannot be read or is not what a CAF must be. parseCaf and verifyCafSignature also refuse a DOCTYPE, and parseCaf a text with more than one <CAF or </CAF and a CAF whose private key is not the pair of its public key (reason: 'RSASK is not the pair of RSAPK'). An empty FRMA is no longer CAF_INVALID: verifyCafSignature answers invalid.reason
CAF_EXPIREDThe CAF is more than 6 months past its authorization date; raised when you stamp.type, authorizationDate
CAF_TYPE_MISMATCHThe CAF is for another document type than the document you are stamping.type, cafType
CAF_ISSUER_MISMATCHThe CAF belongs to another issuer RUT than the document's.type
FOLIO_OUT_OF_RANGEThe folio is outside the CAF range, or a folio ledger or the certification folio allocator runs out of folios.folio, from, to, type

Certificate#

CodeRaised whenTypical details
CERT_INVALIDThe PKCS#12 or PEM cannot be read, has no private key or no certificate, or the key does not match the certificate.reason
CERT_PASSWORD_WRONGThe PKCS#12 password is wrong.none
CERT_EXPIREDThe certificate has expired.expiresAt
CERT_NOT_YET_VALIDThe certificate is not valid yet: its notBefore is still ahead.validFrom

XML and signatures#

CodeRaised whenTypical details
XML_PARSE_FAILEDAn XML cannot be parsed, an element to sign has no ID, or the expected root or closing tag is missing. verifyReceivedDocuments also throws it for a DOCTYPE, an envelope without exactly one SetDTE and a prefixed DTE or Documento. Every DOM the SDK parses refuses elements nested deeper than 100 levels with it, before anything walks them.field, reason, root, line, column
SIGNATURE_NOT_FOUNDA signature is verified on an XML that has no Signature (or no SignedInfo).field
ENVELOPE_EMPTYAn envelope has no documents.kind or field
ENVELOPE_KIND_MISMATCHA document does not belong in this kind of envelope (a receipt in an EnvioDTE, or an invoice in an EnvioBOLETA).kind, type
BOOK_TOTAL_MISMATCHWith strictTotals, an explicit book line total differs from the SII formula.index, expected, actual

Transport#

CodeRaised whenTypical details
TRANSPORT_UNAVAILABLEThere is no fetch in the runtime, or node:https or node:fs could not be loaded by a Node adapter.reason
TRANSPORT_FAILEDThe request failed before a response arrived (DNS, connection refused or reset, a request that cannot be built).reason, operation, responseStarted
TRANSPORT_TLSThe TLS handshake or the certificate verification failed.reason (the OpenSSL or OS code), operation
REQUEST_TIMEOUTThe timeout of the call elapsed.operation, timeoutMs, reason
REQUEST_ABORTEDThe caller's AbortSignal fired.operation

When a transport failure happens after the response headers arrived (while the body was being read), details.responseStarted is true: the SII did answer, at least in part.

SII web services#

CodeRaised whenTypical details
SII_HTTP_ERRORThe SII answered with an HTTP status that is not 2xx.httpStatus, operation, channel, url, body (excerpt, redacted), retryAfterMs
SII_RESPONSE_INVALIDThe answer cannot be interpreted: not the XML or JSON that the channel returns, or without the expected element or code.operation, body
SII_SOAP_FAULTThe SII answered with a SOAP fault.code, reason (redacted), operation
SII_SEED_FAILEDThe SII refused to issue a seed.code, channel
SII_TOKEN_FAILEDThe SII refused to issue a token for a signed seed.code, channel
SII_TOKEN_INVALIDThe SII rejected the token. The client renews it and repeats the call once; this surfaces only if the fresh token is refused too.operation, channel, httpStatus or status or code, attempts
SII_UPLOAD_REJECTEDThe SII refused an upload: a DTEUpload status other than received or duplicate, or more than 500 receipts on the REST channel.status (a number, or 'TOO_MANY'), errors, fileName, operation, message, trackIdElement
SII_QUERY_ERRORA status query answered with a negative code -1 to -14: the query service failed, not your envelope.operation, code, reason
WAIT_TIMEOUTwaitForUploadStatus ran out of time budget while the status was still pending.trackId, attempts, lastCode

Portal#

CodeRaised whenTypical details
SII_PORTAL_LOGIN_FAILEDThe login gave no session.operation, portalMessage
SII_PORTAL_CERT_NOT_ENABLEDThe certificate is not enabled at the SII as a login method.operation, portalMessage
SII_PORTAL_SESSION_LIMITThe SII reports too many authenticated sessions for the RUT.operation
SII_PORTAL_SESSION_EXPIREDThe portal keeps asking to authenticate.operation, step
SII_PORTAL_BLOCKEDThe SII firewall or a captcha blocked the request.operation, step, httpStatus, portalMessage
SII_PORTAL_REJECTEDThe portal understood the request and refused it. details.rejection says why.rejection, operation, plus extras such as portalMessage, file, httpStatus
SII_PORTAL_UNEXPECTED_PAGEThe portal answered a page that cannot be interpreted.operation, step, portalMessage, body

Optional dependencies#

CodeRaised whenTypical details
DEPENDENCY_UNAVAILABLEA function of dte-sdk/pdf needs pdf-lib or bwip-js and it is not installed.module, reason
PDF_RENDER_FAILEDThe PDF library failed while drawing a printed sample.reason, type, folio

Retrying#

isRetryableError(error) is true for:

ErrorCondition
TRANSPORT_FAILED, REQUEST_TIMEOUTalways
SII_RESPONSE_INVALIDalways (a page that cannot be read is usually a passing failure of the service)
SII_QUERY_ERRORalways
SII_HTTP_ERRORhttpStatus 429, 405 or 5xx
SII_UPLOAD_REJECTEDstatus 9 ("system blocked")

It is false for everything else, including TRANSPORT_TLS (a misconfigured trust store does not fix itself) and SII_TOKEN_INVALID (the client already renews the token once). The SII client uses it as the default of retry.retryOn, with exponential backoff and six attempts. Two things to remember:

  • An upload or a claim is not retried just because the error is retryable. Those calls change state at the SII and are sent again only while no answer has arrived. SII_UPLOAD_REJECTED with status 9 is "retryable" by this function, but an upload that got that answer is never re-sent automatically: you decide. See the retry policy.
  • The portal has its own rule, isRetryablePortalError from dte-sdk/portal: transport failures, timeouts, HTTP 502, 503 and 504, and the intermittent TLS failures that the SII produces with a client certificate (EPROTO). A session limit, a block or a rejection is never repeated, because repeating makes them worse. Its policy, DEFAULT_PORTAL_RETRY_POLICY, is 4 attempts at 2, 4 and 8 seconds, without jitter.

Portal rejections#

A SII_PORTAL_REJECTED is the portal refusing a request on business grounds: the company is not enrolled, the quota is exhausted, the backup is blocked. details.rejection is a PortalRejection code. portalRejectionMessage(rejection) and the PORTAL_REJECTIONS map, both from dte-sdk/portal, give the full explanation in Spanish, written for the operator, with what to do about it.

TypeScript
import { isDteError } from 'dte-sdk'
import { portalRejectionMessage, requestCaf, type PortalRejection } from 'dte-sdk/portal'
 
try {
  await requestCaf(portal, { type: 33, quantity: 50 })
} catch (error) {
  if (isDteError(error) && error.code === 'SII_PORTAL_REJECTED') {
    console.error(portalRejectionMessage(error.details.rejection as PortalRejection))
    console.error(error.details.portalMessage) // what the portal said, when it said something
  } else {
    throw error
  }
}

The codes, by area:

ArearejectionMeaning (short)
AccessinPersonRequiredThe legal representative must complete the enrolment in person at an SII office.
companyNotAuthorizedThe company is not authorized as an electronic issuer in this environment. queryAuthorizedIssuer raises it for a RUT that is not in the public registry.
optionNotAuthorizedThe SII says the option is not authorized, without a cause; usually the company is not authorized yet.
userWithoutPermissionThe certificate's RUT has no permissions in the company in this environment, or the SII says the user is not authorized to request stamping ("No está autorizado para solicitar timbraje").
personWithPendingIssuesThe authenticated person has pending matters with the SII.
activityVerificationPendingThe RUT has no activity verification for this document type.
notEnrolledThe company is not enrolled in the electronic invoice application, so the test set cannot be downloaded.
Folios and CAFstampingBlockedThe SII does not authorize stamping: there are enough unused folios.
typeNotEnabledThe SII does not offer this document type for stamping for this RUT.
quotaInsufficient, quotaExceeded, quotaCapReached, foliosShortThe SII authorizes fewer folios than asked, or the request exceeds the maximum.
noAnnullableFoliosStamping is limited and no folios remain that can be annulled.
stampingUncertainThe SII showed the request form again without giving folios or saying why, so it is not known whether it authorized the range. The request is not sent again: check the reobtainable ranges before asking again. requestCafInBatches reports it as such.
rangeAlreadyAuthorized, rangeAnnulledThe range was already authorized (it can be obtained again) or has been annulled.
reobtainFormMissing, reobtainDownloadMissing, reobtainCafMissingThe SII did not return the form, the download or the CAF when obtaining a range again. A login page in their place is SII_PORTAL_SESSION_EXPIRED.
CertificationadvanceRefused, declarationDeclinedThe portal did not advance the application or did not offer the declaration form.
exchangeUploadRefusedThe exchange portal refused a response file (details.file).
samplesReviewRefused, sampleUploadRefusedThe printed samples portal did not create the review, or refused a PDF with a 4xx status.
receiptsNotEnrolled, receiptsTrackIdRefused, receiptsComplianceRefusedThe receipts application refused: not enrolled, the set's track id, or the compliance declaration.
MIPYME backupbackupCaptchaThe SII turned on a captcha. Try later, never in a loop.
backupIndeterminateThe page gave several messages and no single verdict. Try later.
backupNoDataThe SII says there is no information for this RUT. A definitive answer.
backupRefused, backupNoCompanyThe portal refused, or answered the company selection page without a message.
backupDayOverLimit, backupDayUnknownTypesA single day exceeds the 20 documents per download and cannot be split. Nothing was downloaded.
RegisterpurchaseChangeNotConfirmedThe SII did not confirm a change in the purchase register, but it may have been applied: read the document again before retrying.
Activity verificationactivityVerificationRefusedThe SII answered the activity verification with an error code; its words go in details.portalMessage when it said something.

See Portal and Register for the functions behind them.

Status codes#

The SII reports outcomes with short codes. The SDK returns them as data (they are not exceptions), classifies them and gives their Spanish gloss. The glosses are in Spanish because they are the SII's own vocabulary.

TypeScript
import {
  classifyDocumentStatus,
  classifyUploadStatus,
  documentStatusMessage,
  isRetryableStatus,
  isTokenErrorStatus,
  uploadStatusMessage,
} from 'dte-sdk'
 
classifyUploadStatus('EPR') // 'accepted'
classifyUploadStatus('RCT') // 'rejected'
classifyUploadStatus('-11') // 'queryError': retry
classifyUploadStatus('RLV') // 'rejected' on SOAP…
classifyUploadStatus('RLV', 'rest') // …and 'accepted' on the receipts REST API
classifyUploadStatus('XYZ') // 'unknown'
classifyDocumentStatus('FAU') // 'notReceived'
 
uploadStatusMessage('EPR') // 'Envío procesado'
documentStatusMessage('FAU') // 'DTE no recibido por el SII'
isRetryableStatus('-11') // true
isTokenErrorStatus('-3') // true: renew the token and try once more

Upload statuses#

The ESTADO of QueryEstUp (or the REST estado) of an envelope or a book. classifyUploadStatus(code, channel = 'soap') returns one of these classes; uploadStatusMessage(code, channel) the gloss, or Estado desconocido: <code>.

ClassCodes
acceptedEPR (envío procesado), LOK (envío de libro aceptado)
acceptedWithObjectionsRPR (aceptado con reparos)
pendingREC (recibido, esperando validación), SOK (schema validado, validando firma), FOK (firma validada, procesando), PRD (en proceso, validando carátula), CRT (carátula validada, finalizando), DNK (en proceso de revisión), PDR (en proceso, validando), LSO (schema de libro correcto, procesando contenido), 0 (enviado, pendiente de validación)
rejectedRPT (rechazado por schema), RFR (error en firma), VOF (error interno del SII), RCT (error en carátula), RCH (rechazado), RCO (envío rechazado), RSC (error en schema), RLV (error en documento; success on REST), LNC (tipo de envío de libro no corresponde), LRH (libro rechazado con historial)
queryError-1 to -14: failures of the query service, not of your file. -3 and -13 mean the token was refused.
unknownAnything else.

isRetryableStatus(code) is true for the queryError class. isTokenErrorStatus(code) is true for -3, -13, 001, 002 and 003: the client renews the token once when it sees one.

Reception statuses#

The STATUS of the RECEPCIONDTE answer that DTEUpload gives when it takes (or refuses) a file. RECEPTION_STATUS is the catalog, classifyReceptionStatus(code) the class and receptionStatusMessage(code) the gloss. SII_UPLOAD_REJECTED.details.status is this code as a number.

STATUSClassMeaning
0receivedEnvío recibido, TrackID asignado.
1rejectedEl remitente no tiene permiso para enviar por esta empresa.
2rejectedError en el tamaño del archivo (muy grande o muy chico).
3rejectedArchivo cortado o incompleto.
5notAuthenticatedNo autenticado: token ausente o vencido. The client renews the token and sends again once.
6rejectedEmpresa no autorizada a enviar archivos.
7schemaInvalidEsquema inválido o archivo ya enviado (ver DETAIL). The client tells them apart: schema or charset errors (CHR-…, SCH-…, cvc-…) are a rejection; otherwise, with a TrackID in the answer, it is a duplicate.
8rejectedError en la firma del documento.
9rejectedSistema bloqueado, reintentar más tarde. The only one that clears by itself.
99alreadyUploadedArchivo ya fue enviado anteriormente. A duplicate when the answer names the TrackID.

Document statuses#

The ESTADO of QueryEstDte (or the REST codigo) of one document. classifyDocumentStatus(code) and documentStatusMessage(code); any negative code is a queryError, anything else unlisted is unknown.

ClassCodeGloss
receivedDOKDocumento recibido por el SII, datos coinciden
receivedWithMismatchDNKDocumento recibido por el SII, datos no coinciden
notReceivedFAUDTE no recibido por el SII
notAuthorizedFNADTE no autorizado
EMPEmpresa no autorizada a emitir DTE
modifiedTMD, TMCExiste nota de débito o de crédito que modifica textos
MMD, MMCExiste nota de débito o de crédito que modifica montos
cancelledAND, ANCExiste nota de débito o de crédito que anula el documento
FANFolio anulado

Claim and transferability codes#

The registry answers with a codResp number. claimResponseMessage(code) gives the gloss (Código de respuesta desconocido: <code> for a code not listed), and CLAIM_RESPONSE_CODES is the catalog.

codRespGloss
0Acción completada OK
1RUT del emisor erróneo
2Folio erróneo
3El tipo de documento no corresponde
4Acción inválida
5DTE ya reclamado
6No se puede otorgar recibo de mercaderías a un DTE reclamado
7Evento registrado previamente
8Han pasado más de 8 días desde la recepción del documento
9No existen registros para los parámetros indicados
10DTE no recibido en el SII desde el 14-01-2017
11No se puede reclamar un DTE aceptado previamente
12No se puede aceptar un DTE rechazado previamente
13No se puede reclamar un DTE con recibo de mercaderías
14Solo la empresa receptora o emisora puede consultar
15Lista de eventos del documento
16El documento no tiene eventos registrados
17Solo la empresa receptora puede registrar eventos
18Documento no recibido en el SII
19Reclamo por mercaderías ya realizado
27No se puede registrar un evento de un DTE pagado al contado o gratuito
-1Error interno del SII, reintentar

queryTransferable answers with codes 20 to 25. transferabilityMessage(code) gives the gloss, and TRANSFERABILITY_CODES the catalog, with what each implies:

codResptransferableGloss
20falseTipo de documento no cedible
21falseNo cedible: anulado por nota de crédito dentro de los 8 días
22nullSin registro de reclamo ni de recibo de mercaderías
23trueCedible, sin reclamos registrados
24falseNo cedible: reclamado por el receptor
25trueCedible: transcurridos 8 días sin reclamo, se presume recibido

The events that listClaimEvents reports (CLAIM_EVENT_CODES): ACD (acepta contenido), RCD (reclamo al contenido), ERM (otorga recibo de mercaderías o servicios), RFP (reclamo por falta parcial), RFT (reclamo por falta total), NCA (nota de crédito de anulación), ENC (otra nota de crédito) and PAG (DTE pagado al contado, which the SII registers itself).

Code 27 is the registry refusing an event on a document paid in cash or free: production answered it on 11 November 2026 to an acceptance of an invoice whose events listed PAG alone. receiverAnswer reads such a document as paidInCash, so there is nothing to send (see receiverAnswer). Before 0.8.0 the catalog did not know it, and claimResponseMessage(27) gave Código de respuesta desconocido: 27.

Next steps#

  • SII web services shows where these errors and statuses come from, and how retries and token renewal work.
  • Portal explains the session, the limits and the refusals of the portal.
  • Security says what to keep out of your logs.