# PDF gerado pelo meu sistema não abre: o que verificar

Seu sistema gera um PDF que não abre? Confira os primeiros bytes do arquivo, os erros de base64 e de texto no código e o cabeçalho certo para salvar o download.

URL canônica: https://ajustapdf.com/blog/pdf-gerado-pelo-sistema-nao-abre-base64-ou-texto

Publicado em 2026-11-04 · 5 min de leitura · por [AjustaPDF](https://ajustapdf.com/sobre#editorial)

Quando um PDF gerado pelo seu sistema não abre, quase sempre os bytes mudaram no caminho entre o servidor e o disco: foram lidos como texto, decodificados duas vezes ou o download parou no meio. Um PDF válido começa com `%PDF-` logo no primeiro byte. Confira isso antes de mexer no gerador, porque o teste leva um minuto e separa problemas diferentes.

## Primeiro teste: os primeiros bytes do arquivo

Abra o Terminal na pasta do arquivo e rode `head -c 8 relatorio.pdf`. Um arquivo íntegro mostra `%PDF-1.` seguido de um número de versão. No fim, o PDF termina com `%%EOF`, normalmente seguido de uma quebra de linha. Se o começo e o fim estiverem certos e o arquivo ainda não abre, o problema está na estrutura interna, e não no download.

| O que aparece no começo do arquivo | O que provavelmente aconteceu | Onde corrigir |
| --- | --- | --- |
| %PDF-1.7, mas o leitor reclama | Índice interno com defeito | Reparo ou outro leitor |
| Texto só de letras e números, começando por JVBERi0 | Base64 gravado sem decodificar | Código que grava o arquivo |
| <html ou <!DOCTYPE | Página de erro ou de login salva como .pdf | A requisição e a autenticação |
| Mensagem de erro em JSON | O endpoint falhou e o cliente gravou a resposta | O status HTTP da resposta |
| Três bytes EF BB BF antes do %PDF | Marca de ordem de bytes UTF-8 colada no início | Função que escreve o arquivo |
| Começa certo, mas bem menor que o esperado | Download interrompido | Repetir a geração e o download |

## Base64 e texto: os dois erros mais comuns

Sistemas que devolvem o PDF dentro de uma resposta em JSON costumam mandá-lo em base64, um texto de letras, números, + e /. O arquivo só volta a ser PDF depois de decodificado para bytes. Como o cabeçalho `%PDF-` em base64 começa sempre com `JVBERi0`, esse é o sinal mais rápido: se o texto recebido começa assim e o arquivo salvo não abre, o erro está no passo de decodificação.

O segundo erro é tratar bytes como texto. Em Python, com a biblioteca requests, response.text decodifica a resposta como caracteres e troca qualquer byte acima de 127; response.content entrega os bytes crus. Em JavaScript, res.text() tem o mesmo efeito. Em Node, escrever uma string com fs.writeFile sem indicar codificação binária corrompe o arquivo da mesma forma: crie um Buffer com `Buffer.from(base64, "base64")` e grave esse Buffer.

Decodificar duas vezes também quebra o arquivo, e acontece mais do que parece: a biblioteca HTTP já decodifica uma camada e o código decodifica de novo. Conte quantas vezes o conteúdo passa por uma função de decodificação antes de gravar.

## Cabeçalho Content-Type e download

Um servidor que responde `Content-Type: text/html` para um PDF faz o navegador salvar uma página no lugar do arquivo, ou mudar a extensão sem avisar. O valor correto para PDF é `application/pdf` (o tipo MIME do PDF e o download que abre como texto). Esse cabeçalho não estraga os bytes, mas esconde o problema: o arquivo salvo parece PDF e não abre. Para conferir, abra a aba Rede (Network) do DevTools no Chrome ou no Edge, repita o download e veja o cabeçalho da resposta.

Se o tamanho do arquivo em KB é muito menor do que o gerador deveria produzir, a conexão caiu ou o servidor fechou antes do fim. Gerar e baixar de novo resolve. Se o problema se repete só em redes lentas, compare o tamanho recebido com o campo de tamanho da resposta, quando o servidor envia esse campo.

## Quando o arquivo está certo e só o leitor reclama

Se o arquivo começa com `%PDF-` e termina com `%%EOF`, ele está no lugar. Abra em outro leitor antes de culpar o gerador (se só aparecem páginas pretas, o caso é o de [PDF que abre com tela preta](/blog/pdf-tela-preta-ao-abrir)). Leitores diferentes reagem de forma diferente a um índice interno com defeito: um abre, outro pede reparo. Nesse caso, a ferramenta [Reparar PDF](/reparar-pdf) reconstrói o índice e copia as páginas como estão; se a estrutura estiver danificada demais, ela redesenha as páginas legíveis num PDF novo.

## Como corrigir na origem

1.  Grave o conteúdo como bytes. Em Python, use o modo `wb` ou response.content; em Node, um Buffer; no Android, o mesmo cuidado vale ao gravar o PDF pelo MediaStore, como em gerar PDF no Android com Kotlin.
2.  Decodifique o base64 uma vez, no ponto em que a resposta chega, e não em duas funções diferentes.
3.  Responda com `Content-Type: application/pdf` e, se o arquivo for para download, `Content-Disposition: attachment` com o nome terminando em .pdf, o que no Laravel o `download` do DomPDF já faz, como mostra gerar PDF no Laravel com DomPDF.
4.  Teste o arquivo que está no disco, com `head -c 8`, e não o que a tela mostrou.
5.  Gere um PDF mínimo, de uma página com um texto, e confira se ele abre. Se o mínimo abre e o seu não, o defeito está no conteúdo gerado, não no caminho de entrega.

## O que o reparo não resolve

Reparar recupera a estrutura de um arquivo que existiu por inteiro, não o conteúdo que nunca chegou. Se o arquivo começa com `<html`, a resposta de erro foi salva com outro nome e não há PDF para recuperar. Nesse caso, o AjustaPDF devolve a mensagem dizendo que não há conteúdo legível, e a tentativa não conta na cota diária. A correção está na requisição, não no arquivo.

O mesmo vale para um PDF que pede senha. Senha não é defeito: o arquivo está íntegro e criptografado, e quem resolve é o desbloqueio, e não o reparo. Se o seu sistema gera PDFs com [senha de abertura](/glossario#senha-de-abertura), o leitor precisa dessa senha para abrir, e isso não indica que o arquivo saiu quebrado.

## Quando vale enviar o arquivo para o reparo

O reparo é útil para o arquivo que já existe e está quebrado, enquanto você corrige o gerador ou quando não controla o sistema que o produziu. Ele não substitui a correção de origem, e um gerador que devolve arquivo quebrado vai continuar devolvendo. Use a ferramenta para salvar o arquivo de hoje e o código para salvar o de amanhã. Se o problema não for esse, o [diagnóstico de PDF corrompido que não abre](/blog/pdf-corrompido-nao-abre) cobre as outras causas. E se o PDF abre bem e só o sistema que o recebe recusa o conteúdo, veja [PDF com conteúdo não reconhecido em sistema](/blog/sistema-diz-conteudo-do-pdf-nao-reconhecido).

## Perguntas frequentes

### Meu sistema gera PDF em base64 e o arquivo baixado não abre, o que checar?

Confira se o texto recebido começa com JVBERi0, que é como o base64 de “%PDF-” aparece. Se começa, o sistema devolveu o PDF codificado e o seu código precisa decodificar antes de gravar o arquivo. Se não começa, o problema está antes: a resposta não é o PDF.

### Como saber se o arquivo baixado é um PDF de verdade e não uma página de erro salva com .pdf?

Um PDF íntegro começa com %PDF-1 seguido de um número de versão, como 1.4 ou 1.7. Se os primeiros bytes forem <html ou <!DOCTYPE, o servidor mandou uma página de erro ou de login. No Terminal, o comando head -c 8 arquivo.pdf mostra esses bytes sem abrir nenhum programa.

### O PDF gerado começa com %PDF e mesmo assim o leitor diz que está corrompido: tem conserto?

Quase sempre sim. Um arquivo com cabeçalho certo costuma ter o índice interno gravado com posições erradas, comum em geradores de PDF feitos à mão. O reparo reconstrói esse índice e copia as páginas; se não bastar, redesenha o que for legível. Se o arquivo estiver cortado antes da primeira página, ou se o que chegou nem é PDF, não há o que recuperar.

### Por que o PDF que minha API devolve aparece com caracteres estranhos quando eu salvo?

Porque os bytes do PDF foram tratados como texto em UTF-8, e qualquer byte acima de 127 foi trocado. Em Python com requests, use response.content em vez de response.text. Em JavaScript, grave o resultado de res.arrayBuffer() como Buffer, e não como string.
