Navigation

Frequently Asked Questions

Common Extension Installation Errors

PHP Headers Not Found

For example:

/private/tmp/pear/install/mongodb/php_phongo.c:24:10: fatal error: 'php.h' file not found

#include <php.h>
         ^~~~~~~

This error indicates that PHP’s build system cannot find the necessary headers. All PHP extensions require headers in order to compile. Additionally, those headers must correspond to the PHP runtime for which the extension will be used. Generally, the phpize command (invoked by pecl) will ensure that the extension builds with the correct headers.

Note that the mere presence of a PHP runtime does not mean that headers are available. On various Linux distributions, headers are often published under a separate php-dev or php-devel package. On macOS, the default PHP runtime does not include headers and users typically need to install PHP (and headers) via Homebrew in order to build an extension.

Multiple PHP Runtimes Installed

If your system has multiple versions of PHP installed, each version will have its own pecl and phpize commands. Additionally, each PHP runtime may have separate php.ini files for each SAPI (e.g. FPM, CLI). If the extension has been installed but is not available at runtime, double-check that you have used the correct pecl command and have modified the appropriate php.ini file(s).

If there is any doubt about the php.ini file being used by a PHP runtime, you should examine the output of phpinfo() for that particular SAPI. Additionally, php_ini_loaded_file() and php_ini_scanned_files() may be used to determine exactly which INI files have been loaded by PHP.

To debug issues with the extension not being loaded, you can use the detect-extension script provided in the tools directory. You can run this script from the CLI or include it in a script accessible via your web server. The tool will point out potential issues and installation instructions for your system. Assuming you’ve installed the library through Composer, you can call the script from the vendor directory:

php vendor/mongodb/mongodb/tools/detect-extension.php

If you want to check configuration for a web server SAPI, include the file in a script accessible from the web server and open it in your browser. Remember to wrap the script in <pre> tags to properly format its output:

<pre><?php require(...); ?></pre>

Loading an Incompatible DLL on Windows

Windows binaries are available for various combinations of PHP version, thread safety (TS or NTS), and architecture (x86 or x64). Failure to select the correct binary will result in an error when attempting to load the extension DLL at runtime:

PHP Warning:  PHP Startup: Unable to load dynamic library 'mongodb'

Ensure that you have downloaded a DLL that corresponds to the following PHP runtime properties:

  • PHP version (PHP_VERSION)
  • Thread safety (PHP_ZTS)
  • Architecture (PHP_INT_SIZE)

In addition to the aforementioned constants, these properties can also be inferred from phpinfo(). If your system has multiple PHP runtimes installed, double-check that you are examining the phpinfo() output for the correct environment.

The aforementioned detect-extension script can also be used to determine the appropriate DLL for your PHP environment.

Server Selection Failures

The following are all examples of Server Selection failures:

No suitable servers found (`serverSelectionTryOnce` set):
  [connection refused calling hello on 'a.example.com:27017']
  [connection refused calling hello on 'b.example.com:27017']

No suitable servers found: `serverSelectionTimeoutMS` expired:
  [socket timeout calling hello on 'example.com:27017']

No suitable servers found: `serverSelectionTimeoutMS` expired:
  [connection timeout calling hello on 'a.example.com:27017']
  [connection timeout calling hello on 'b.example.com:27017']
  [TLS handshake failed: -9806 calling hello on 'c.example.com:27017']

No suitable servers found: `serverselectiontimeoutms` timed out:
 [TLS handshake failed: certificate verify failed (64): IP address mismatch calling hello on 'a.example.com:27017']
 [TLS handshake failed: certificate verify failed (64): IP address mismatch calling hello on 'b.example.com:27017']

These errors typically manifest as a MongoDB\Driver\Exception\ConnectionTimeoutException exception from the driver. The actual exception messages originate from libmongoc, which is the underlying library used by the PHP driver. Since these messages can take many forms, it’s helpful to break down the structure of the message so you can better diagnose errors in your application.

Messages will typically start with “No suitable servers found”. The next part of the message indicates how server selection failed. By default, the PHP driver avoids a server selection loop and instead makes a single attempt (according to the serverSelectionTryOnce connection string option). If the driver is configured to utilize a loop, a message like “serverSelectionTimeoutMS expired” will tell us that we exhausted its time limit.

The last component of the message tells us why server selection failed, and includes one or more errors directly from the topology scanner, which is the service responsible for connecting to and monitoring each host. Any host that last experienced an error during monitoring will be included in this list. These messages typically originate from low-level socket or TLS functions.

The following is not meant to be exhaustive, but will hopefully point you in the right direction for analyzing the contributing factor(s) for a server selection failure:

  • “connection refused” likely indicates that the remote host is not listening on the expected port.
  • “connection timeout” could indicate a routing or firewall issue, or perhaps a timeout due to latency.
  • “socket timeout” suggests that a connection was established at some point but was dropped or otherwise timeout out due to latency.
  • “TLS handshake failed” suggests something related to TLS or OCSP verification and is sometimes indicative of misconfigured TLS certificates.

In the case of a connection failure, you can use the connect tool to try and receive more information. This tool attempts to connect to each host in a connection string using socket functions to see if it is able to establish a connection, send, and receive data. The tool takes the connection string to a MongoDB deployment as its only argument. Assuming you’ve installed the library through Composer, you would call the script from the vendor directory:

php vendor/mongodb/mongodb/tools/connect.php mongodb://127.0.0.1:27017

In case the server does not accept connections, the output will look like this:

Looking up MongoDB at mongodb://127.0.0.1:27017
Found 1 host(s) in the URI. Will attempt to connect to each.

Could not connect to 127.0.0.1:27017: Connection refused

Note

The tool only supports the mongodb:// URI schema. Using the mongodb+srv scheme is not supported.