NF-e

Rejeição 539 e 204 na NF-e e NFC-e: Arquitetura de Idempotência no Retry, Auto-Reconciliação SEFAZ e Inutilização via API

Como eliminar de vez a Rejeição 539 (Duplicidade de NF-e com diferença na Chave de Acesso) e 204 em retries de rede, reconciliar protocolos na SEFAZ (NFeConsultaProtocolo4) e inutilizar numeração (POST /api/v1/nfe/inutilizar).

Fábio Magalhães CostaAtualizado em 26/10/2026
Engenharia de resiliência e idempotência para emissão de NF-e e NFC-e em alta disponibilidade sem Rejeição 539 ou 204

Engenharia de resiliência e idempotência para emissão de NF-e e NFC-e em alta disponibilidade sem Rejeição 539 ou 204

Qualquer engenheiro que já manteve um emissor de NF-e (Modelo 55) ou NFC-e (Modelo 65) sob carga pesada conhece a seguinte sequência de eventos: a aplicação envia o lote para o webservice NFeAutorizacao4 da SEFAZ, a conexão sofre um ETIMEDOUT ou ECONNRESET aos 15 segundos, a fila de mensageria faz o retry automático da nota e, na segunda tentativa, a SEFAZ responde com Rejeição 539: Duplicidade de NF-e, com diferença na Chave de Acesso.

Pior ainda: em dias de instabilidade ou pico de vendas como a Black Friday, um retry mal projetado pode chavear a nota para contingência (SVC-AN ou SVC-RS) depois que a SEFAZ de origem já havia recebido e autorizado o primeiro envio silenciosamente — gerando dupla autorização fiscal ou buracos na sequência numérica da série que obrigam a contabilidade a inutilizar faixas às pressas.

A única forma de erradicar a Rejeição 539 na NF-e e NFC-e é persistir o artefato completo de emissão (número nNF, série, tpEmis, código aleatório cNF de 8 dígitos, chave de 44 posições e XML assinado) com lock pessimista (FOR UPDATE) ANTES do envio SOAP, reutilizando exatamente a mesma chave em qualquer retry e reconciliando via NFeConsultaProtocolo4.

Na release v0.56.54 / w0.33.52 da Notaas, nós redesenhamos toda a camada de guarda de retry, auto-reconciliação SEFAZ e inutilização de numeração (POST /api/v1/nfe/inutilizar). Neste artigo, vou abrir a arquitetura exata que implementamos nos nossos workers.

Quando uma requisição para a SEFAZ sofre timeout de leitura (ETIMEDOUT), você não sabe se a nota morreu no caminho ou se já foi autorizada lá dentro. Gerar um novo cNF aleatório no retry é pedir para tomar Rejeição 539.

Por que a Rejeição 539 acontece em filas assíncronas (RabbitMQ, BullMQ, SQS)

A Chave de Acesso de 44 dígitos de uma NF-e ou NFC-e é formada por: cUF (2) + AAMM (4) + CNPJ (14) + mod (2) + serie (3) + nNF (9) + tpEmis (1) + cNF (8) + cDV (1).

Na maioria dos emissores tradicionais, quando um worker consome uma mensagem da fila para emitir a nota de número 1050 na série 1, ele executa um pipeline linear em memória:

  1. Sorteia um código numérico aleatório de 8 dígitos (cNF = Math.floor(Math.random() * 90000000) + 10000000).
  2. Monta a chave de 44 dígitos, gera o XML <NFe> e assina digitalmente com o certificado A1.
  3. Abre o socket TLS e dispara o NFeAutorizacao4 para a SEFAZ.
  4. Salva a chave e o protocolo no banco de dados após a resposta.

O problema fatal está na ordem entre os passos 3 e 4. Se a SEFAZ processar e autorizar a nota 1050 com cNF = 48291034, mas a conexão TCP cair antes do seu worker ler o XML de retorno (ECONNRESET), o worker lança exceção e devolve a mensagem para a fila (nack).

Quando o retry roda 5 segundos depois para a mesma nota 1050, o código sorteia outro cNF aleatório (digamos, cNF = 91827364), gerando uma nova chave de 44 dígitos para o mesmo CNPJ + mod + serie + nNF. Ao bater na SEFAZ, o autorizador estadual detecta que a nota 1050 já existe com outra chave e devolve:

cStat 539 - Rejeição: Duplicidade de NF-e, com diferença na Chave de Acesso [chNFe: 352610...][nProt: 135260...].


A arquitetura de 4 camadas contra Rejeição 539/204 que implementamos na Notaas

Para resolver esse problema na raiz em ambiente distribuído (com múltiplos workers rodando em paralelo no Docker Swarm), nós estruturamos o nfe-retry-guard da Notaas em quatro barreiras determinísticas:

⚡ Pipeline de Emissão NF-e/NFC-e Idempotente (Zero Erro 539):

  • 1. Lock Pessimista e Persistência Pré-SOAP (claimOrCreateEmissionArtifact): Executa SELECT ... FOR UPDATE na invoice, aloca n_nf, gera cNF, monta e assina o <NFe> completo (incluindo QR Code na NFC-e) e faz COMMIT no banco antes de chamar a SEFAZ.
  • 2. Reuso Estrito do Artefato no Retry (inspectStoredEmissionArtifact): Se a tentativa anterior sofreu timeout, o retry lê a chave_acesso e o nfe_xml já assinados do banco e reenvia exatamente o mesmo payload.
  • 3. Guarda de Contingência SVC (canSwitchToSvcOnNetworkError): Só permite chavear automaticamente para SVC-AN/SVC-RS (tpEmis 6/7) em falhas pré-conexão (ECONNREFUSED, ENOTFOUND) ou cStat 108/109, nunca após timeout de leitura.
  • 4. Auto-Reconciliação (reconcileSefazAuthorization): Ao detectar cStat 204 ou 539 (ou recibo pendente), extrai a chave/protocolo ou consulta NFeConsultaProtocolo4, reconstrói o <nfeProc> autorizado e gera o DANFE automaticamente.

Camada 1 e 2: Persistência do XML assinado antes da rede

Ao gravar n_nf, serie, tp_emis, chave_acesso e nfe_xml assinado no PostgreSQL antes de abrir a conexão HTTP com a SEFAZ, garantimos que o código aleatório cNF nunca mude entre tentativas da mesma nota.

Além disso, se dois workers receberem entrega duplicada da fila ao mesmo tempo, o SELECT * FROM nfe_invoices WHERE id = $1 FOR UPDATE serializa o acesso e impede que uma nota que já entrou em status = 'issued' ou status = 'error' seja retransmitida acidentalmente.

Camada 3: Quando é seguro (e quando é perigoso) chavear para SVC-AN / SVC-RS

Como detalhamos no nosso artigo sobre contingência automática SVC-AN e SVC-RS na NF-e, mudar o tpEmis de 1 (Normal) para 6 ou 7 (SVC) altera o 35º dígito da Chave de Acesso.

Por isso, nossa função canSwitchToSvcOnNetworkError() diferencia rigorosamente dois tipos de erro de rede:

  • Falha Pré-Conexão (ECONNREFUSED, ENOTFOUND, EHOSTUNREACH) ou SEFAZ Paralisada (cStat 108/109): Nenhum byte do XML foi entregue ao servidor de origem. É 100% seguro regerar o artefato com tpEmis = 6/7 e emitir via SVC.
  • Falha Pós-Envio (ETIMEDOUT, ECONNRESET durante leitura): O XML pode ter sido processado na SEFAZ normal. O worker mantém o artefato original (tpEmis = 1) e consulta o protocolo antes de qualquer decisão.

Camada 4: Auto-Reconciliação com NFeConsultaProtocolo4

E se a primeira tentativa realmente foi autorizada na SEFAZ durante um timeout de rede? Quando o segundo envio bate na SEFAZ com a mesma chave (retornando cStat 204 - Duplicidade de NF-e) ou se houver divergência (cStat 539), nossa rotina reconcileSefazAuthorization() entra em ação:

  1. Extrai a chave e o protocolo informados pela própria SEFAZ na mensagem de rejeição (extractSefazDuplicityHints) ou dispara uma consulta ao webservice NFeConsultaProtocolo4.
  2. Quando o retorno confirma cStat = 100 (Autorizado o uso da NF-e) ou 150 com <protNFe> válido, a Notaas acopla o <protNFe> ao <NFe> assinado para montar o <nfeProc versao="4.00">, salva o PDF do DANFE no storage, marca a nota como issued e dispara o webhook nota.autorizada para o seu ERP — transformando o que seria um erro crítico em uma emissão concluída de forma transparente!

E quando um número realmente precisa ser inutilizado? (POST /api/v1/nfe/inutilizar)

Mesmo com reciclagem inteligente de numeração (nfe_numeros_liberados), existem cenários operacionais — como migração de um ERP antigo para a Notaas ou descarte manual de uma tentativa que avançou na numeração — em que a legislação exige a Inutilização de Numeração de NF-e/NFC-e (NFeInutilizacao4, retorno cStat 102).

Para que você não precise montar e assinar o XML < inutNFe versao="4.00"> na mão (cujo atributo Id exige exatamente ID + cUF + ano (2) + CNPJ + mod + serie (3) + nNFIni (9) + nNFFin (9)), disponibilizamos o endpoint direto POST /api/v1/nfe/inutilizar:

curl -X POST "https://platform.notaas.com.br/api/v1/nfe/inutilizar" \
  -H "Authorization: Bearer ntaas_live_sua_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "modelo": 55,
    "serie": 1,
    "numeroInicial": 1048,
    "numeroFinal": 1049,
    "justificativa": "Quebra de sequencia numerica durante migracao de sistema emissor"
  }'

O endpoint valida a justificativa (mínimo de 15 caracteres exigido pela SEFAZ), verifica se não existe nenhuma nota autorizada naquela faixa dentro do seu projeto, assina o evento com o certificado A1, transmite para a SEFAZ da UF correspondente (incluindo SVRS e SVAN), persiste o XML <ProcInutNFe> e já remove esses números da fila de reciclagem para que nunca mais sejam reutilizados:

{
  "success": true,
  "data": {
    "id": "inut_99281726",
    "cStat": 102,
    "xMotivo": "Inutilizacao de numero homologado",
    "protocolo": "135260009182736",
    "modelo": 55,
    "serie": 1,
    "numeroInicial": 1048,
    "numeroFinal": 1049
  }
}

Se você também lida com operações interestaduais complexas ou devoluções de mercadorias, vale conferir nosso guia sobre como emitir NF-e com ICMS ST e devolução sem Rejeição W16-10 e como preencher Pedido de Compra (xPed e nItemPed) via API.


Emita NF-e e NFC-e com resiliência de nível bancário

Pare de apagar incêndios de duplicidade na SEFAZ ou perder horas reconciliando notas que deram timeout.

  • Plano Free (R$ 0/mês): 20 notas fiscais gratuitas por mês em Produção (1 CNPJ) + até 5 projetos simultâneos em Homologação via Org API.
  • Plano Dev (R$ 99/mês): 500 notas/mês + até 3 CNPJs em Produção.
  • Plano SaaS Pro (R$ 249/mês): 2.000 notas/mês + CNPJs ilimitados em Produção e Homologação.

👉 Criar Conta Gratuita na Notaas · Explorar Documentação NF-e / NFC-e

Notaas — Infraestrutura Fiscal Multi-Tenant para SaaS, ERPs e BPOs

Escale a emissão de NFS-e, NF-e, NFC-e, CT-e e MDF-e para dezenas de CNPJs

Integre a API de Nota Fiscal da Notaas no seu software: provisione clientes via Org API Multi-CNPJ, isole certificados A1 em nuvem, receba webhooks assinados com HMAC e gere DANFSe v2.0 local. Sandbox ilimitado e planos sob medida para operações em escala.

Artigos Relacionados em NF-e

NFS-e • 26/10/2026

Como emitir NFS-e Nacional com Prestador Pessoa Física (CPF e CAEPF) via API REST

Guia técnico para emitir NFS-e Nacional (SNNFSE) com prestador Pessoa Física (CPF) e inscrição CAEPF via API JSON: formação do ID da DPS (tpInscr=1), tags <CPF> e <CAEPF>, cancelamento com <CPFAutor>, DANFSe v2.0 e gestão multi-cliente via Org API.

NFS-e • 26/10/2026

Integração NFS-e Híbrida (Pronim/Cidade360, SpeedGov e ISSNet Nacional): Como resolver os erros E376, E0617 e e101103

Bastidores técnicos da integração de NFS-e nos provedores híbridos do Padrão Nacional: Pronim/Cidade360 (/NFSe.Api/NotaNacional em 137 cidades), SpeedGov (<DadosDPS> E376/E390) e ISSNet Nacional em Brasília/DF e Goiânia/GO (E0617 e e101103).

NF-e • 26/10/2026

Rejeições 434, 438 e 591 na NF-e e NFC-e: Intermediador de Marketplace (indIntermed), CRT 2 (Sublimite) e Base de PIS/COFINS

Guia prático para resolver as Rejeições SEFAZ 434/438 (indIntermed e infIntermed em Marketplaces e Delivery), Rejeição 591 (CRT 2 Simples Nacional Excesso de Sublimite com ICMS CST) e Exclusão do ICMS da Base de PIS/COFINS (vBCPis/vBCCofins).

NFS-e • 24/10/2026

Emissor de NFS-e Nacional em Node.js (Open Source) vs. API Gratuita: o que aprendi mantendo código fiscal em produção

Análise técnica e prática sobre criar um emissor de NFS-e Nacional próprio em Node.js e TypeScript ou usar uma API REST com 20 notas grátis por mês. mTLS, OpenSSL legacy, DANFSe v2.0 local (@notaas/danfse-viewer) e NT-009.

Guias Pilares de Integração Fiscal