Securimage FAQ

Note: Securimage is a legacy self-hosted PHP CAPTCHA. While still usable, modern applications should consider newer alternatives such as hCaptcha or Cloudflare Turnstile.

Real questions from Securimage users, with real answers.

Fatal error: Call to undefined function imagecreatetruecolor()

PHP's GD extension is not installed or enabled. Check:

  1. Upload server_test.php from the Securimage package and open it in a browser
  2. It tells you whether GD is enabled and which features are available

On Windows: Edit your php.ini and uncomment the line ;extension=php_gd2.dll by removing the semicolon. Restart your web server.

On Linux (Ubuntu/Debian):

sudo apt-get install php-gd
  sudo systemctl restart apache2   # or nginx + php-fpm

If GD is enabled but you still get the error, your GD version may be too old. As a workaround, change imagecreatetruecolor to imagecreate in securimage.php.

Fatal error: Call to undefined function imagettftext()

GD is enabled but FreeType (TTF font) support wasn't compiled in. The server test output shows this as "TTF Support (FreeType): No".

On Linux, install the FreeType-enabled GD:

sudo apt-get install php-gd libgd3 libfreetype6-dev
  sudo systemctl restart php8.1-fpm   # match your PHP version

Or skip TTF entirely — set $img->use_gd_font = true; in securimage_show.php. Lower image quality, but it works without FreeType.

CAPTCHA fails on my live server but works locally

Almost always a session problem. The usual culprit: your form processor outputs HTML before calling session_start().

Fix: Make the very first line of your form processor:

<?php session_start(); ?>

Before any HTML output, whitespace, or other PHP code. Even a blank line before <?php can trigger headers-already-sent errors on some servers.

To debug: Add this at the top of both your form processor and securimage.php:

<?php
  error_reporting(E_ALL);
  ini_set('display_errors', 'on');
  

You'll see the exact error and where it's happening.

The code is always invalid, even when typed correctly

Four common causes:

  1. Session not starting — see the answer above about session_start()
  2. GET vs POST mismatch — if your form uses method="get", change $_POST['captcha_code'] to $_GET['captcha_code'] in your form processor
  3. Checking the code too early — if you validate the CAPTCHA before other form checks, the session code gets consumed even when other fields fail. Put the CAPTCHA check last
  4. Image refreshed after submission — each time the CAPTCHA image loads, a new code is generated. If your form reloads the image on error, the old code is gone

CAPTCHA fails when user hits the browser back button

When the user goes back and resubmits, they see the old code — but Securimage has already generated a new one. By design, each code is single-use.

Best fix: prevent caching on your form processor with header('Cache-Control: no-store, no-cache, must-revalidate'). On back-navigation the form reloads fresh with a new CAPTCHA.

Alternatively, only clear the session code on successful validation — not on failure. Easier for users, but weaker against brute-force.

My form processor shows a blank page after submission

Blank page = a PHP error with error display turned off. Add this at the top of your processor:

<?php
  error_reporting(E_ALL);
  ini_set('display_errors', 'on');
  

Once you can see the error, the fix is usually obvious.

How do I use a background image?

Pass the full path to your image in securimage_show.php:

<?php
  // Last line of securimage_show.php
  $img->show('/full/path/to/securimage/backgrounds/bg.jpg');
  

PNG, JPG, or GIF. It gets resized if dimensions don't match. For random backgrounds from a directory, see the customization guide.

How do I enable the audio CAPTCHA?

Audio WAV files aren't in the main package — download audio.zip separately from the GitHub releases page and extract it into your Securimage directory.

Then set the audio path in securimage_show.php:

<?php
  $img->audio_path = dirname(__FILE__) . '/audio/';
  

For the play button, add a link that calls the Securimage audio URL using the same session ID as the image.

Image not displaying on GoDaddy hosting

GoDaddy and some shared hosts inject HTML footer ads into PHP output. This corrupts the CAPTCHA — image bytes get mixed with HTML.

Fix: add a .htaccess file in the Securimage directory:

AddType application/x-httpd-php .png

Rename securimage_show.php to securimage_show.png and update your image tag. The host's injection script won't touch PNG files.

Integrating with Smarty templates

In your Smarty template, add the image and input:

<img src="/securimage/securimage_show.php" alt="CAPTCHA" />
  <input type="text" name="captcha_code" />

In your PHP form processor (the Smarty controller), validate:

<?php
  session_start();
  include 'securimage.php';

  $img = new Securimage();
  $code = $_POST['captcha_code'];

  if ($img->check($code) == false) {
      // Code incorrect — re-display form with error
  }
  

Will two users interfere with each other's CAPTCHA codes?

No. Each code lives in the user's PHP session, tied to their session cookie. User A and User B are completely isolated. One caveat: each user can only have one active code at a time. If a user loads the CAPTCHA image twice, only the second code is valid.

Changing code_length doesn't work

Bug in early versions. Upgrade to the latest release from GitHub. In current versions, $img->code_length = 6; in securimage_show.php works as expected.

PHP source code is showing instead of the CAPTCHA image

PHP isn't installed or isn't configured to handle .php files. Quick test: create info.php with <?php phpinfo(); ?> and open it in a browser. If you see raw PHP code instead of a table of settings, PHP isn't running.

Talk to your host, or check that your web server is set up to process .php files.

How do I make the "different image" link work?

Add a JavaScript onclick that swaps the img element's src with a fresh random query string. This forces a new server request (and a new code):

<a href="#" onclick="
    document.getElementById('captcha').src =
    '/securimage/securimage_show.php?' + Math.random();
    return false">[ Different Image ]</a>

Is Securimage compatible with PHP 8?

Yes. The current GitHub version supports PHP 7.2 through 8.x. Running something pre-3.0? Upgrade from GitHub.

Do I have to use an image CAPTCHA?

No. For many sites, a honeypot hidden field stops most spam bots with zero user friction. For serious bot protection, Cloudflare Turnstile is invisible and free. See our CAPTCHA alternatives guide for a full comparison.

Still having trouble?

Check the GitHub issues page — plenty of edge cases have been reported and solved there. For setup or configuration help, see the quickstart guide and customization options.