Pular para o conteúdo principal

Cenários de erro 400 (BadRequest) na emissão de NFS-e

Esta página lista os cenários em que a API de NFS-e responde HTTP 400 (BadRequest) ao emitir uma nota ou ao cancelá-la. Um 400 significa que a requisição foi rejeitada por validação de payload ou por regra de negócio — antes de a nota ser enviada à prefeitura.

Para a visão geral de todos os status HTTP (401, 408, 500, 503, 504), consulte Tipos de retorno de status das requisições HTTPS. Para diagnóstico passo a passo por sintoma, consulte Solução de erros 400 na emissão de NFS-e.

Como interpretar o corpo do erro 400

Existem dois tipos de erro 400, com corpos diferentes:

Validação de formato (desserialização do JSON)

Quando o corpo enviado não pode ser interpretado — JSON malformado ou tipo incompatível (por exemplo, enviar federalTaxNumber ou servicesAmount como texto não numérico) — a API responde 400 com um corpo ProblemDetails (JSON estruturado), antes de qualquer regra de negócio. As chaves de errors são o caminho do campo no JSON ($.campo):

{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": {
"$.borrower.federalTaxNumber": [
"The JSON value could not be converted to System.Int64. Path: $.borrower.federalTaxNumber | LineNumber: 0 | BytePositionInLine: 736."
]
},
"traceId": "00-<trace-id>-<span-id>-00"
}

Regras de negócio (validação e estado)

Os cenários das tabelas abaixo retornam um corpo de texto simples, em uma destas formas:

  • Mensagem única — uma frase descrevendo a regra violada. Exemplo: Municipal tax is not allowed to issue invoice.
  • Lista de mensagens — quando vários campos falham na mesma requisição, as mensagens vêm concatenadas (uma por regra violada).
  • Sem corpo — alguns cenários retornam 400 com corpo vazio. Nesses casos, identifique a causa pela operação e pelo contexto da requisição (ver coluna "Mensagem retornada" marcada como sem corpo).
nota

As mensagens de negócio são retornadas em inglês, exatamente como nas tabelas abaixo. Trate-as como literais ao exibir para o usuário final ou ao casar por texto em automações.

Validação do payload de emissão

Disparados ao validar o corpo do POST /v1/companies/{companyId}/serviceinvoices. Quando mais de uma regra falha, as mensagens são agregadas em uma única resposta.

Campo / regraCondição que dispara o 400Mensagem retornadaComo evitar
Bodycorpo da requisição nuloBody can not be nullEnvie um corpo JSON válido
cityServiceCodenulo ou vaziocityServiceCode can not be null or emptyInforme o código de serviço municipal
descriptionnula ou vaziadescription can not be null or emptyInforme a descrição do serviço
servicesAmount< 0servicesAmount can not be less than 0.00Use valor de serviço >= 0
rpsSerialNumberinformado com comprimento 0rpsSerialNumber can not be less than zeroOmita o campo ou informe uma série não vazia
rpsNumberinformado <= 0rpsNumber can not be less than or equal zeroUse número de RPS > 0
issRate< 0issRate can not be less than 0.00 (0%)Use alíquota entre 0% e 5%
issRate> 0,05issRate can not be more than 0.05 (5%)Use alíquota <= 0.05 (5%)
deductionsAmount< 0deductionsAmount can not be less than zeroUse valor >= 0
discountConditionedAmount< 0discountConditionedAmount can not be less than zeroUse valor >= 0
discountUnconditionedAmount< 0discountUnconditionedAmount can not be less than zeroUse valor >= 0
irAmountWithheld< 0irAmountWithheld can not be less than zeroUse valor >= 0
pisAmountWithheld< 0pisAmountWithheld can not be less than zeroUse valor >= 0
cofinsAmountWithheld< 0cofinsAmountWithheld can not be less than zeroUse valor >= 0
csllAmountWithheld< 0csllAmountWithheld can not be less than zeroUse valor >= 0
inssAmountWithheld< 0inssAmountWithheld can not be less than zeroUse valor >= 0
issAmountWithheld< 0issAmountWithheld can not be less than zeroUse valor >= 0
othersAmountWithheld< 0othersAmountWithheld can not be less than zeroUse valor >= 0
approximateTax.totalRate< 0approximateTax.TotalRate can not be less than 0.00 (0%)Use percentual >= 0
approximateTax.totalRate> 99,99approximateTax.TotalRate can not be more than 99.99 (99.99%)Use percentual <= 99.99
ibsCbs.classCodeinformado e diferente de 6 dígitosibsCbs.classCode must be exactly 6 digitsInforme exatamente 6 dígitos
ibsCbs.operationIndicatorinformado e diferente de 6 dígitosibsCbs.operationIndicator must be exactly 6 digitsInforme exatamente 6 dígitos
construction.encapsulationNumberinformado fora de 1 a 12 dígitosconstruction.encapsulationNumber must contain from 1 to 12 digitsInforme de 1 a 12 dígitos
additionalInformationcomprimento > 500additionalInformation length must be less than 500 charactersLimite o texto a 500 caracteres
location.citylocation presente com city nulolocation.city can not be nullInforme a cidade do local da prestação
location.city.codenulo ou vaziolocation.city.code can not be null or emptyInforme o código IBGE da cidade
location.city.codediferente de 7 dígitoslocation.city.code must be a valid IBGE city codeUse o código IBGE de 7 dígitos
location.city.namenula ou vazialocation.city.name can not be null or emptyInforme o nome da cidade
location.statenula ou vazialocation.state can not be null or emptyInforme a UF
location.statediferente de 2 caractereslocation.state must be a valid ISO 3166-2 code, samples (SP, RJ, AC)Use a sigla da UF com 2 letras
borrower.namecomprimento > 115borrower.name length must be less than 115 charactersLimite o nome a 115 caracteres
borrower.federalTaxNumbertomador no Brasil sem CPF nem CNPJ válidoborrower.federalTaxNumber borrower federal tax number is not validInforme CPF ou CNPJ válido
borrower.federalTaxNumbertipo NaturalPerson com CPF inválidoborrower.federalTaxNumber is not valid for natural personUse CPF válido para pessoa física
borrower.federalTaxNumbertipo LegalEntity com CNPJ inválidoborrower.federalTaxNumber is not valid for legal personUse CNPJ válido para pessoa jurídica
borrower.phoneNumberinformado com menos de 7 dígitosborrower.phoneNumber can not be less than 7 digitsUse telefone com 7 a 19 dígitos
borrower.phoneNumberinformado com 20 dígitos ou maisborrower.phoneNumber can not be longer than 20 digitsUse telefone com no máximo 19 dígitos
dica

Tomador estrangeiro (borrower.address.country diferente de BRA) pula a validação de CPF/CNPJ. Use o country correto para evitar rejeição indevida do documento fiscal.

nota

A ausência do bloco borrower não retorna 400 na emissão. Ainda assim, informe o tomador: ele é necessário para a nota ser concluída — sem ele, a validação ocorre apenas adiante (consulta da nota/prefeitura).

Endereço do tomador (quando country = BRA)

Disparados por ValidateAddress. Um endereço totalmente vazio é aceito; ao informar qualquer campo, os demais passam a ser exigidos.

Campo / regraCondição que dispara o 400Mensagem retornadaComo evitar
borrower.address.countrycódigo fora da tabela ISO 3166-1borrower.address.country must be a valid ISO 3166-1 code, samples (BRA, ARG, COL)Use o código de país de 3 letras
borrower.address.postalCodenulo ou vazioborrower.address.postalCode can not be null or emptyInforme o CEP
borrower.address.streetnulo ou vazioborrower.address.street can not be null or emptyInforme o logradouro
borrower.address.citynulaborrower.address.city can not be nullInforme a cidade
borrower.address.statenula ou vaziaborrower.address.state can not be null or emptyInforme a UF
borrower.address.statediferente de 2 caracteres ou com espaçoborrower.address.state must be a valid ISO 3166-2 code, samples (SP, RJ, AC)Use a sigla da UF com 2 letras
borrower.address.city.code/namecódigo ou nome da cidade vazioborrower.address.city.code or borrower.address.city.name can not be null or emptyInforme código IBGE e nome
borrower.address.city.codediferente de 7 dígitosborrower.address.city.code must be a valid IBGE city codeUse o código IBGE de 7 dígitos
borrower.address.stateUF inexistente na baseborrower.address.state is not a valid state codeUse uma UF válida
borrower.address.city.codecidade inexistente na baseborrower.address.city.code is not a valid city code or cityUse um código IBGE existente
borrower.address.city.code + stateUF não corresponde ao prefixo do código IBGEborrower.address.city.code and borrower.address.state aren't related. inform the correct state associated with correct city codeGaranta que cidade e UF sejam coerentes
borrower.address.stateUF da base difere da informadaborrower.address.state from DB differs of city state informedGaranta que cidade e UF sejam coerentes

Comércio exterior (foreignTrade)

Validados apenas quando o bloco foreignTrade é informado.

Campo / regraCondição que dispara o 400Mensagem retornadaComo evitar
foreignTrade.serviceModevalor fora do enumforeignTrade.serviceMode is invalidUse um valor de enum válido
foreignTrade.relationShipvalor fora do enumforeignTrade.relationShip is invalidUse um valor de enum válido
foreignTrade.currencynula ou vaziaforeignTrade.currency can not be null or emptyInforme a moeda
foreignTrade.serviceAmountInCurrencynuloforeignTrade.serviceAmountInCurrency can not be nullInforme o valor em moeda estrangeira
foreignTrade.serviceAmountInCurrency< 0foreignTrade.serviceAmountInCurrency can not be less than zeroUse valor >= 0
foreignTrade.supportMechanismProvidervalor fora do enumforeignTrade.supportMechanismProvider is invalidUse um valor de enum válido
foreignTrade.supportMechanismReceivervalor fora do enumforeignTrade.supportMechanismReceiver is invalidUse um valor de enum válido
foreignTrade.temporaryGoodsvalor fora do enumforeignTrade.temporaryGoods is invalidUse um valor de enum válido
foreignTrade.mdicDeliverynuloforeignTrade.mdicDelivery can not be nullInforme o indicador de entrega ao MDIC

Regras de emissão

Disparados de forma síncrona depois da validação do payload, no POST /v1/companies/{companyId}/serviceinvoices. Quando a mensagem é sem corpo, identifique a causa pelo contexto da empresa.

CenárioCondição que dispara o 400Mensagem retornada
Imposto municipal inativohabilitação fiscal da empresa diferente de "ativa" (em produção)Municipal tax is not allowed to issue invoice
Empresa inativaempresa com status diferente de "ativa"company is not active
RPS duplicadojá existe nota com o mesmo número de RPSservice invoice with rps number ({rpsNumber}) already exists
externalId duplicadojá existe nota com o mesmo externalIdservice invoice with external id ({externalId}) already exists
Corpo da nota nulorequisição sem dados da notasem corpo
atenção

RPS ou externalId duplicado pode retornar 400 (e não 409). Não trate duplicidade assumindo um código de status fixo; verifique a mensagem retornada.

nota

Outras validações (certificado digital, habilitação por código de serviço, regravação) ocorrem após o enfileiramento, no processamento assíncrono da nota. Elas não retornam 400 na chamada de emissão — o resultado é entregue na consulta da nota, no status e na mensagem de fluxo.

Cancelamento da nota

OperaçãoCondição que dispara o 400Mensagem retornada
Cancelamento (DELETE /{id})imposto municipal inativo (em produção)Municipal tax is not allowed to issue invoice

Veja também

Para IA / LLMs

  • Cobertura: cenários que fazem a API de NFS-e responder HTTP 400 (BadRequest) na emissão e no cancelamento da nota.
  • Versão aplicável: API de NFS-e v1. Regras de validação são da plataforma NFE.io; a rejeição da prefeitura é posterior e não gera 400.
  • Não parafrasear: a coluna "Mensagem retornada" é literal (retornada em inglês pela API). Reproduza a mensagem original ao responder; a coluna "Como evitar" pode ser interpretada.
  • Corpo do erro: dois tipos. Validação de formato/desserialização → ProblemDetails JSON ({ "errors": {...}, "status": 400 }). Regras de negócio → texto simples (mensagem única ou lista concatenada) ou vazio.
  • Síncrono vs assíncrono: só os cenários listados retornam 400 na chamada. Certificado, código de serviço e regravação ocorrem no processamento assíncrono e não viram 400 — chegam na consulta da nota.
  • Pré-requisitos: Tipos de retorno de status das requisições HTTPS.
  • Atualizado: 2026-06-27 por revisão humana.

NFE.io

A NFE.io é uma empresa de tecnologia que fornece soluções para automatizar e simplificar a emissão e gestão de notas fiscais eletrônicas. Com suas ferramentas, as empresas podem economizar tempo e reduzir erros, aumentando a eficiência e precisão do processo de emissão de notas fiscais.

Um dos principais cases de sucesso da NFE.io é a implementação da solução na empresa de transporte Rodonaves. Com a automatização da emissão e gestão de notas fiscais eletrônicas, a Rodonaves conseguiu reduzir em até 80% o tempo gasto nesse processo, o que se traduziu em uma significativa melhoria na eficiência operacional. Além disso, a empresa também conseguiu eliminar erros e atrasos na emissão de notas fiscais, o que melhorou a relação com seus clientes e aumentou a confiança dos órgãos fiscais.

Outro exemplo é a implementação da NFE.io na empresa de comércio eletrônico, a Loja Integrada. Com a automatização da emissão de notas fiscais, a Loja Integrada conseguiu aumentar a velocidade de emissão de notas em até 10 vezes, o que permitiu que a empresa atendesse a uma maior quantidade de clientes e, consequentemente, aumentar as suas vendas.

Além desses exemplos, a NFE.io também tem outros cases de sucesso com empresas de setores como indústria, construção, varejo e serviços, mostrando a versatilidade e eficácia da sua solução.

Em resumo, a NFE.io é uma empresa de tecnologia que oferece soluções para automatizar e simplificar a emissão e gestão de notas fiscais eletrônicas, ajudando as empresas a economizar tempo e reduzir erros, melhorando a eficiência e precisão do processo. Com cases de sucesso em diferentes setores, a NFE.io tem se destacado como uma empresa líder em automação fiscal.