Apache2 with PDF and PHP - "This file does not start with "%PDF-" Apache2 with PDF and PHP - "This file does not start with "%PDF-" nginx nginx

Apache2 with PDF and PHP - "This file does not start with "%PDF-"


This is really tough to troubleshoot - for starters, (please excuse my bluntness, but) this a prime example of what a pipeline should not look like:

  • Three different operating systems.
  • Probably at least two different versions of PHP.
  • Two different webservers.

But anyway, a few general hints on debugging PHP:

  • make sure to enable error_log and log_errors in php.ini (set display_errors = Off)
  • use the most verbose error_reporting
  • set access_log and error_log in nginx.
  • crank up log level in nginx (I'm guessing you use php-cgi or php-fpm, so you should be able to see what status the backend emits when the download attemp fails).

Furthermore:

  1. You haven't shared how the PDF is generated - are you sure all libraries used here are the same or at least somewhat the same across all systems?
  2. In any case, just to be sure I would save the PDF on the server before it is offered to download. This allows you to troubleshoot the actual file — to see if the PDF generation actually worked.
  3. Since you're saving the PDF, I'd see about putting it in a public folder, so you can see if you can just redirect to it after it's generated. And only if this works, then I'd work on a force-download kind of thing.
  4. I would replicate the production environment in all stages. ;-) You need your dev server to be exactly like the production environment. For your own workstation, I'd recommend a VM (e.g. through Virtualbox with Ubuntu 10.10).

Let me know this gets you somewhere and reply with updates. :-)

Update:

I'd investigate these two headers:

header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past

Definitely helps with cache busting.


These are the headers, which finally worked in a similar situation in one of my apps:

header("Pragma: public");header("Expires: 0");header("Cache-Control: must-revalidate, post-check=0, pre-check=0");header("Cache-Control: private",false);header( "Content-Type: application/pdf" );header("Content-Disposition: inline; filename=\"YourPDF_" . time() . ".pdf\";");header("Content-Transfer-Encoding: binary");header("Content-Length: ". strlen( $pdfData ) );

I added the time() code to make the filename change each time, so that it likely passes all proxies.

From time to time but seldom, the problem re-appears. Then, we ask our clients to download the file using the browser context menu.

PS: The app uses ezPDF found here: http://www.ros.co.nz/pdf/