Troubleshooting CGI Scripts

We've all seen CGI scripts cough up the dreaded "Internal Server Error" message occasionally! What does this error mean, and how can you find the cause of the problem? This tutorial explains some CGI troubleshooting techniques.

If you've tried running a few CGI scripts on your Web server, you've probably come across a few problems now and again. Usually, when your script has a problem, you will see an error message similar to the following in your Web browser:


Internal server Error

The server encountered an internal error
and was unable to complete your request.

It's not a very helpful message, is it! Fortunately there are ways to find out the exact cause of your script error. In this tutorial we look at methods that you can use to troubleshoot your scripts, and also list some common causes of CGI errors.

Finding the exact error message

The problem with an error message like "Internal Server Error" is that it doesn't tell you exactly what the problem is. In fact, all this error message means is that your script failed to output the required HTTP headers, which probably means that it did not run properly.

If you're lucky and you're running a more recent Web server, such as Apache 2.0, then you may see a bit more detail such as:


Error message:
Premature end of script headers: formmail.cgi

Still, this message simply confirms that our script didn't output the required HTTP headers, and therefore didn't run correctly.

What we really need is the error message output by the Perl interpreter - this will usually tell us the exact problem, and where the problem is in our script. For example:


String found where operator expected at test.cgi
line 6, near "prunt "hello""
        (Do you need to predeclare prunt?)
syntax error at test.cgi line 6, near "prunt "hello""
Execution of test.cgi aborted due to compilation errors.

This allows us to pinpoint the problem much more easily - in this case, that we mis-typed the word print as prunt!

Look in the error log

If you have access to your Web server's error log, the first thing to try is to look in the error log for the error message. If you're not sure where your error log is stored, as your Web hosting company for help.

Take a look at the last few error messages in the log. You'll probably see the "Premature end of script headers" message in there, but below it you should see the actual error message output by the Perl interpreter, such as "syntax error at test.cgi line 6...".

Check the script's syntax

What if you can't access your Web server's error log? In that case, you will need to check the script's syntax directly using Perl, bypassing the Web server.

Most CGI script errors are caused by simple syntax mistakes in the script. This is especially true when you've first created or uploaded your script.

Syntax errors can be caused by many things, including:

  • Mis-typing or mis-spelling part of the script
  • Failing to upload the script in ASCII (Text) mode
  • Incomplete upload of the script

To check your script's syntax, you will need to ssh to your Web server. (If your Web server doesn't allow ssh access, you can set up your own test Web server to test your scripts - see below.) If you need help with using ssh, take a look at our ssh and basic commands tutorial.

Once you've connected to your server with ssh, change to the directory containing your CGI script (usually cgi-bin or cgi-shl). You can then get Perl to check the syntax of your script by using the command:


$ perl -c test.cgi

(Replace test.cgi with the name of the CGI script you want to test!)

Perl will then display any syntax errors with the script, along with their line numbers. This should enable you to track down and fix your syntax errors.

If you get the message:


test.cgi syntax OK

then there are no syntax errors with your script, and the problem lies elsewhere.

Run the script via ssh

If your script's syntax is fine, then it may be causing a run-time error. To detect this, you will need to actually run your script and see if Perl outputs any errors at this stage.

To run the script, type:


$ ./test.cgi

or:


$ perl test.cgi

(If you use the first method, and get a message such as:


/usr/bin/perl: bad interpreter: No such file or directory

then the problem is that the path to Perl in the first line of your script is wrong. For more information on the path to Perl, read the Your first CGI script tutorial.)

When you run the script, you will see the exact output from your script appear in the ssh window, and/or any run-time error messages generated by Perl. This should help you debug your script further.

Note that your script must output the Content-type HTTP header before anything else. (If it doesn't do this, you will get the Internal Server Error.) So make sure that the first two lines of your script's output are something like:


Content-type: text/html
(blank line)

There must be that blank line after the Content-type line. For more information, see the Your first CGI script tutorial.

Common causes of script errors

If you can't easily test your script via ssh as shown above, then there are few things worth checking before you go any further. These are the most common problems that can cause the Internal Server Error message.

Uploading the script in Binary mode

If you've been editing the script on a Mac or Windows PC, the script will contain either Mac or Windows end-of-line characters. If you then try to upload this script as it is to a UNIX or Linux Web server and run it, you will probably get script errors, because Perl on the Web server can't recognize the end-of-line characters you've used.

Luckily, most FTP programs allow you to upload the file in ASCII mode (sometimes called Text mode). By doing this, the end-of-line characters are automatically converted to UNIX format when the file is uploaded.

Make sure you have turned on ASCII or Text mode before uploading your CGI scripts. A lot of FTP programs allow you to specify files that should automatically be uploaded in ASCII mode, based on the filename extension (such as .cgi and .pl).

Incomplete or corrupted uploads

Sometimes FTP uploads fail half-way through, leaving only half the script uploaded! Check that the file sizes of the file on your PC and the file on the server are the same, or similar (they may vary a bit if you're uploading in ASCII mode). If the file on the server is a lot smaller, try uploading it again.

Wrong path to Perl

If you're running the script on a UNIX or Linux server, then the path to the Perl interpreter, specified in the first line of the script, must be correct. If it isn't, then the Web server won't know how to run your script, and you'll get an Internal Server Error.

For more information on the path to Perl, read the Your first CGI script tutorial.

Incorrect permissions

Generally speaking, if you need to run a script on your Web server, the script file will need to have execute permission for at least the owner, and often for everybody. Usually the script will also need read permission for the same users.

It's also generally a bad idea to allow a script file to be writable by anybody except the script's owner. Apart from the security risks, some Web servers are configured to that you can't run so-called "world-writable" scripts.

If your script file has the wrong permissions, you will often get a Forbidden error message, although you might see the Internal Server Error error message instead.

If you're using a UNIX or Linux Web server, you can usually set your file permissions via FTP (often the feature is called CHMOD). Try setting your script file permissions to 755 (or rwxr-xr-x) - this will give everyone permission to read and execute the script, but only you will have the ability to modify the script.

Other things to try

If you can't debug your script by looking at the Perl error messages via ssh, and you've checked out all the common causes of script errors listed above, then there are a couple more things you can try.

Set up a test server

You can download and install a test Web server on your own PC. This will allow you to test the script locally (as an alternative to having to ssh to your Web server). It's also generally much faster to debug and test scripts locally on your own PC, as you don't have to keep uploading the file to the remote Web server!

Also, if you are planning on writing any CGI scripts of your own, then a test server on your own PC will make development much quicker and easier.

If you're running a Windows, MacOS X or Linux PC at home, you can download and install the Apache Web server for free. Get it from the Apache Web server website. You'll find instructions there for installing the Web server and setting up your Web site on your PC.

If you're running Linux or MacOS X, then the Apache Web server will probably already be installed on your PC. If you're a Mac-head, there's a good article on Web serving with Apache on MacOS X on O'Reilly's Web site.

If you have a Windows server operating system then it probably has Microsoft Internet Information Server already installed. This is another Web server that you can use to develop and test your scripts.

You'll also need Perl running on your PC. If you're using Linux or MacOS X, this will probably be on your system already. If not, you can download it from the Perl website.

If you're running Windows, ActiveState have produced a version of Perl, called ActivePerl, that runs well on Windows. You can download it from the ActiveState website.

Piecemeal debugging

This is really a last resort when all of the above methods have failed! If you can't work out which part of your Perl script is causing the error, try breaking up the script into smaller pieces of code, and running each piece as a separate script.

This will enable you to track down the error to a particular part of your scripts. You can then work on getting this part working, at which point you will hopefully have fixed the problem!

Turn on warnings and strict checking

Actually, if you're serious about Perl programming, then warnings and strict checking are things you should really use first, rather than last! They encourage good programming practice and help you to catch problems at an early stage, before they turn into bugs.

However, they can make life difficult for beginners, so we haven't mentioned them so far. We'll talk about them in detail in a later tutorial on good programming techniques.

To turn on Perl warnings, add the switch -w to the first line of your Perl script, e.g.:


#!/usr/bin/perl -w

This will then warn you about things in your code that might cause problems. The warnings are usually placed in the web server's error log. It's usually a good idea to remove the -w switch again once you've tested and debugged your script, to avoid filling up your error log with unnecessary warnings!

To use strict checking, add the line:


use strict;

near the top of your script. Perl will now insist that you do things like declare variables before you use them (e.g. "my $variable_name"). It can be frustrating at first, but you'll write better code as a result.

Follow Elated

Related articles

Responses to this article

2 responses (oldest first):

07-May-10 02:10
Good article.

It might be worth mentioning $! and...

use CGI::Carp qw/fatalsToBrowser/;

...in order to display error messages.
07-May-10 02:53
Great points Sam. In fact I keep meaning to add CGI::Carp to this article - it's on my to-do list.

Matt

Post a response

Want to add a comment, or ask a question about this article? Post a response.

To post responses you need to be a member. Not a member yet? Signing up is free, easy and only takes a minute. Sign up now.

Top of Page