Pular para o conteúdo

Solução de problemas do Gotenberg no NextPDF

A bridge falha de forma explícita e logo no início. Cada falha lança uma exceção tipada com uma mensagem que identifica a causa. Use esta página como um catálogo. Para cada falha, você encontra o tipo da exceção, o fragmento da mensagem que verá, o gatilho exato no caminho do código e a correção.

As famílias de exceções são:

  • GotenbergConvertException — uma falha na camada de conversão (configuração, transporte ou resposta).
  • RuntimeException — uma falha na camada de validação, lançada pela política de segurança antes de qualquer tráfego de rede.
  • ValueError — uma extensão de arquivo não reconhecida.
  • InvalidSpkiPinException — uma string de pin Transport Layer Security (TLS) SubjectPublicKeyInfo (SPKI) malformada.

”Invalid Gotenberg configuration: apiUrl is empty”

Seção intitulada “”Invalid Gotenberg configuration: apiUrl is empty””
  • Tipo: GotenbergConvertException
  • Gatilho: Você chamou convertFile() ou convertString() enquanto GotenbergConfig::isValid() é false. Isso acontece quando apiUrl é uma string vazia.
  • Correção: Forneça uma URL HTTPS não vazia. Se você monta a configuração com fromArray(), observe que ele substitui silenciosamente '' por um api_url ausente ou que não seja uma string. Valide a origem da configuração durante a inicialização.

Essas falhas vêm da política de segurança, que protege contra server-side request forgery (SSRF). A bridge as lança antes de enviar qualquer requisição. Cada uma é uma RuntimeException simples.

”Gotenberg API URL must use HTTPS (got: http)”

Seção intitulada “”Gotenberg API URL must use HTTPS (got: http)””
  • Gatilho: O esquema da URL configurada não é https. A verificação não diferencia maiúsculas de minúsculas, então HTTPS:// é aceito.
  • Correção: Coloque o Gotenberg atrás de TLS e configure o endpoint HTTPS. HTTP simples é rejeitado mesmo para desenvolvimento local.
  • Gatilho: A URL não pode ser analisada em um esquema e um host.
  • Correção: Forneça uma URL absoluta sintaticamente válida, por exemplo https://gotenberg.example.com:3000.

O endereço resolve para um IP privado ou reservado — “Gotenberg API URL must not resolve to a private or reserved IP address”

Seção intitulada “O endereço resolve para um IP privado ou reservado — “Gotenberg API URL must not resolve to a private or reserved IP address””
  • Gatilho: O host é um literal Internet Protocol (IP) privado ou reservado, ou um nome de host que resolve (por todos os registros A/AAAA) para qualquer endereço privado ou reservado. Isso bloqueia os intervalos privados da Request for Comments (RFC) 1918, endereços de loopback e link-local.
  • Correção: Aponte a bridge para um endereço público roteável ou para um endereço de serviço devidamente segmentado. Se o seu Gotenberg estiver intencionalmente em uma rede privada, a proteção SSRF da bridge o rejeitará por design. Exponha-o por meio de um endereço aceito pela proteção e, em seguida, proteja esse caminho com controles de rede e autenticação. Consulte /integrations/gotenberg/security-and-operations/.

”Gotenberg API URL DNS answer changed since validation — possible DNS rebinding attack”

Seção intitulada “”Gotenberg API URL DNS answer changed since validation — possible DNS rebinding attack””
  • Gatilho: Entre a validação inicial e a requisição, uma nova resolução Domain Name System (DNS) retornou um endereço que não estava no conjunto originalmente validado.
  • Correção: É a proteção time-of-check/time-of-use sendo acionada. Investigue o DNS do host. Uma causa legítima é um balanceador de carga rotacionar endereços. Uma causa maliciosa é um ataque de rebinding. Use um endereço estável ou um nome com um conjunto de registros estável para o endpoint do Gotenberg.

A política de segurança lança essas falhas antes da requisição. Cada uma é uma RuntimeException simples, salvo indicação em contrário.

Arquivo não encontrado ou ilegível — “File not found or not readable:

Seção intitulada “Arquivo não encontrado ou ilegível — “File not found or not readable: ””
  • Tipo: GotenbergConvertException
  • Gatilho: convertFile() não conseguiu canonicalizar o caminho, ou o caminho resolvido não é um arquivo comum legível. Um diretório também aciona essa falha.
  • Correção: Passe o caminho de um arquivo existente e legível. O caminho é canonicalizado primeiro com realpath(), o que também impede traversal.

”File size ( bytes) exceeds maximum allowed size ( bytes)”

Seção intitulada “”File size ( bytes) exceeds maximum allowed size ( bytes)””
  • Gatilho: A entrada é maior que maxFileSize (padrão 52.428.800 bytes = 50 MiB).
  • Correção: Aumente maxFileSize se o documento legitimamente precisar disso, ou rejeite o upload em uma camada anterior. Mantenha o limite tão baixo quanto seus documentos reais permitirem. É o único limite de recurso embutido da bridge.

A bridge valida o nome do arquivo. Para conversões de arquivo, o nome do arquivo é o basename do caminho resolvido; para convertString(), é o nome que você informa. Cada uma destas falhas é uma RuntimeException:

Fragmento da mensagemGatilho
must not be emptynome de arquivo vazio
path traversal sequences (..)o nome contém ..
forward slasheso nome contém /
backslasheso nome contém \
null byteso nome contém um byte NUL
control characterso nome contém um caractere de controle ASCII (0–31)
  • Correção: Passe um basename limpo. Para convertString(), forneça um nome simples como report.docx. Ele é usado para detecção de formato e como nome de arquivo no upload multipart, não como caminho.
  • Tipo: ValueError
  • Gatilho: A extensão do arquivo não é uma destas: docx, xlsx, pptx, odt, ods, odp (não diferencia maiúsculas de minúsculas, ponto inicial tolerado).
  • Correção: Converta apenas os seis formatos reconhecidos. A bridge não reconhece os formatos binários legados (.doc, .xls, .ppt), .rtf, .csv, texto simples ou imagens. Converta essas entradas para um formato reconhecido antes de chamar a bridge, ou encaminhe-as por outro caminho.

Todas estas são GotenbergConvertException.

  • Gatilho: O cliente PHP Standard Recommendation 18 (PSR-18) (ou o transporte com pinning de cURL) lançou uma exceção ao enviar a requisição. A causa é uma conexão recusada, um timeout, uma falha de handshake TLS ou uma incompatibilidade de pin.
  • Código da exceção: o código da exceção do cliente subjacente.
  • Causa: a exceção original do cliente PSR-18 é anexada como a exceção anterior.
  • Correção: Verifique quatro coisas. Verifique a acessibilidade do serviço com isAvailable(). Verifique o caminho de rede. Verifique a cadeia TLS. Se o pinning estiver configurado, verifique se o SubjectPublicKeyInfo (SPKI) atual do servidor corresponde a um pin configurado. Uma incompatibilidade de pin após uma rotação de certificado é a causa clássica. Consulte o procedimento de rotação em /integrations/gotenberg/security-and-operations/.
  • Gatilho: O curl_exec do transporte com pinning de cURL falhou com um número de erro cURL diferente de zero ou retornou um corpo que não é uma string.
  • Correção: O número de erro cURL identifica a causa (TLS, resolução, timeout, pin). Uma falha de pinning surge aqui quando CURLOPT_PINNEDPUBLICKEY rejeita o certificado. Confirme se os pins configurados e o endereço resolvido estão atualizados.
  • Gatilho: O status da resposta não foi 200. O corpo é incluído, truncado aos primeiros 500 caracteres, com reticências anexadas quando for mais longo.
  • Correção: Leia o corpo incluído. A mensagem de erro do Gotenberg explica por que a conversão foi rejeitada: conteúdo de documento não suportado, uma falha interna do LibreOffice ou uma rejeição de autenticação com 401 ou 403. Um 401/403 significa que a apiKey está ausente ou incorreta. Um 5xx é uma falha do lado do serviço e candidata a uma nova tentativa limitada.

”Unexpected Content-Type from Gotenberg: (expected application/pdf)”

Seção intitulada “”Unexpected Content-Type from Gotenberg: (expected application/pdf)””
  • Gatilho: O status foi 200, mas o Content-Type da resposta não continha application/pdf.
  • Correção: Isso geralmente significa que um proxy ou gateway retornou uma página de erro HTML ou de redirecionamento com um 200. A bridge desativa deliberadamente o acompanhamento de redirecionamentos no transporte com pinning, de modo que uma resposta 3xx não é seguida silenciosamente para um host não verificado. Um corpo recebido com o Content-Type errado sinaliza que algo entre você e o Gotenberg está interferindo. Inspecione o caminho de rede.

O corpo da resposta não começa com o cabeçalho %PDF — “Response body does not start with %PDF header — invalid PDF data”

Seção intitulada “O corpo da resposta não começa com o cabeçalho %PDF — “Response body does not start with %PDF header — invalid PDF data””
  • Gatilho: Status 200, Content-Type aceitável, mas o corpo não começa com a assinatura %PDF.
  • Correção: O upstream retornou algo que não é um arquivo Portable Document Format (PDF), apesar dos cabeçalhos. Trate a resposta como não confiável e investigue o serviço. Não grave o corpo em disco. A bridge se recusa a retorná-lo como resultado.
  • Tipo: InvalidSpkiPinException
  • Gatilho: Uma string de pin configurada não começa com sha256/ nem com sha256//.
  • Correção: Formate cada pin como sha256/<base64-encoded-spki-hash>. O transporte também aceita a forma nativa de cURL sha256//<base64>. Gere o valor a partir do SubjectPublicKeyInfo do certificado do servidor, não a partir do certificado inteiro.

Relata indisponibilidade, mas o serviço está no ar — “It says unavailable but the service is up”

Seção intitulada “Relata indisponibilidade, mas o serviço está no ar — “It says unavailable but the service is up””

isAvailable() retorna false sem nenhuma chamada de rede quando a URL está vazia, não é HTTPS ou resolve para um endereço private/reserved. Ele também retorna false em qualquer erro de rede ou quando /health retorna 500 ou mais; nesses casos, ele captura o erro em vez de lançá-lo. Verifique, nesta ordem:

  1. A URL configurada é não vazia e HTTPS.
  2. O host não resolve para um endereço private/reserved (a proteção SSRF o rejeita mesmo para a sondagem).
  3. <apiUrl>/health está acessível a partir do host da aplicação e retorna um status abaixo de 500.
  • /integrations/gotenberg/configuration/ — todas as opções e regras de seleção de transporte.
  • /integrations/gotenberg/production-usage/ — política de novas tentativas e o contrato de tratamento de falhas.
  • /integrations/gotenberg/security-and-operations/ — o modelo de SSRF e a rotação de pins.
  • /integrations/gotenberg/quickstart/ — a ordem exaustiva de captura em contexto.