Debugging CGI Scripts

Debugging CGI scripts: error logs, command-line testing, and common fixes

How do I find out why my CGI script is returning a 500 error?

Check the web server's error log first: Apache logs CGI errors to error_log, Nginx logs them to error.log. The most specific error message is almost always there. If you have SSH access, test the script directly from the command line with the appropriate environment variables set; you will see the exact output the server sees, making header and syntax errors obvious. Add CGI::Carp (Perl) or cgitb (Python) for development to redirect errors to the browser response.

Request CGI help Getting started

The error log is the first place to look

A 500 Internal Server Error from a CGI script almost never tells you what went wrong in the browser; the detail is in the server error log. On Apache, the error log is at /var/log/apache2/error.log (Debian/Ubuntu) or /var/log/httpd/error_log (RHEL/CentOS), or the path set in the ErrorLog directive for your virtual host. On shared hosting, cPanel typically shows the error log in the Errors section of the control panel. The log entry will say something like 'Premature end of script headers' or 'Can't locate CGI.pm in @INC' or 'Permission denied'.

Premature end of script headers means the script exited without printing a valid Content-Type header and a blank line before the body. This covers a range of underlying causes: a syntax error that prevents the script from running at all, a runtime error early in the script, or output printed before the header. All show up as the same 500 to the browser but have different error log messages that distinguish them.

Testing CGI scripts from the command line

You can run any CGI script outside the web server by setting the required environment variables manually. For a GET request: REQUEST_METHOD=GET QUERY_STRING='name=test&value=123' perl myscript.cgi. For a POST: set REQUEST_METHOD=POST, CONTENT_TYPE=application/x-www-form-urlencoded, and CONTENT_LENGTH to the byte count of the body, then pipe the body to the script via standard input. The script runs exactly as it would under the web server, and you see its complete output, making header problems immediately visible.

This technique is especially useful for debugging scripts that work from the command line with no environment set but fail through the server, which usually points to a missing module, a wrong path, or a runtime error triggered by specific input that you can reproduce by setting QUERY_STRING.

Common CGI errors and their fixes

Premature end of script headers: the script printed something before the Content-Type header, or exited without printing any headers. Find and move all output after the header line. Can't locate Module.pm in @INC: a required Perl module is not installed on the server. Install it via CPAN or ask your host; on shared hosting you may need to request the module or use a local lib path. Permission denied: the script file lacks execute permissions (chmod 755) or is in a directory the server user cannot enter (check parent directory permissions). No such file or directory on the interpreter: the shebang path is wrong for this server; use 'which perl' or 'which python3' to find the correct path.

Malformed header from script, not a valid header name character: the script printed a blank line before the Content-Type header, or printed a non-header line first. This often comes from a use statement or BEGIN block that produces output, or a UTF-8 BOM at the start of the file that precedes the shebang. Save the file without a BOM and ensure the shebang is the absolute first bytes in the file.

What to know

Key points

Get help

Listings and a local agent, when you are ready

Need a CGI script built, debugged, or a hosting environment configured? Forms use a clearly-marked placeholder endpoint until wired to a real system.

Hosting partner CGI-compatible hosting for CGI debugging

Reserved for an affiliate link to a vetted shared or VPS hosting provider that supports CGI and Perl/Python execution. Operator wires affiliate link here.

Development Need a custom CGI script built?

Self-hosted lead form for custom CGI development inquiries. Placeholder endpoint until wired to the operator's CRM or email handler.

Open inquiry form →

Custom CGI development

No spam. Your inquiry is answered within 1 business day.

Hosting setup help

No spam. Your inquiry is answered within 1 business day.

Questions

Frequently asked questions

What does 'Premature end of script headers' mean?
It means the CGI script exited before printing a valid HTTP header block (Content-Type plus a blank line). The most common causes are a syntax or runtime error that kills the script before it reaches the print header line, or some output (including warning messages) appearing before the Content-Type header. Check the error log for the underlying error, and add CGI::Carp or cgitb to redirect errors to the browser response during debugging.
How do I see Perl or Python error messages from a CGI script?
In Perl: add 'use CGI::Carp qw(fatalsToBrowser);' near the top of the script; fatal errors will be sent to the browser response body instead of only to the error log. In Python: add 'import cgitb; cgitb.enable()' at the top. Both redirect tracebacks to the browser during development. Remove them before the script serves real users, since they expose internal paths and module details.

CustomCGI publishes reference information on CGI programming and server-side web scripting for educational and informational purposes. Code examples are provided as-is for learning; always audit and test scripts in a staging environment before deploying to production. Security vulnerabilities in CGI scripts are a real risk; follow current best practices and review the security guide before deploying any user-facing code.