Skip to content

Troubleshooting

Sascha Greuel edited this page Aug 2, 2026 · 1 revision

Troubleshooting

Home · Servers and ports · Global options

Start with a minimal query

Reduce the problem to one server, an explicit ID, and no optional filters:

use GameQ\Exception\ProtocolException;
use GameQ\Exception\QueryException;
use GameQ\Exception\ServerException;
use GameQ\GameQ;

try {
    $gameQ = new GameQ();
    $gameQ->setOption('debug', true);
    $gameQ->addServer([
        'id' => 'test',
        'type' => 'css',
        'host' => '192.0.2.10:27015',
    ]);

    var_export($gameQ->process()['test']);
} catch (ServerException | QueryException | ProtocolException $exception) {
    error_log($exception::class . ': ' . $exception->getMessage());
}

Run this from the same PHP runtime, container, user, and network namespace as the failing application.

Server is always offline

Check in this order:

  1. The type matches the game and server edition.
  2. host contains the client port, not a guessed query port.
  3. A custom query_port is configured when the game server uses one.
  4. The game server has its query interface enabled.
  5. The PHP host can send and receive the protocol's UDP or TCP traffic.
  6. Provider, container, host, and remote firewalls allow both the request and response path.
  7. The selected protocol does not require a public master-list entry or credentials.

A successful game connection does not prove that the separate query endpoint is enabled or reachable.

Buffer or malformed-response exception

Errors about an out-of-bounds read, invalid header, truncated packet, checksum, or malformed JSON/XML usually mean one of the following:

  • the wrong type or query port was selected;
  • the server returned a partial response;
  • a mod or game update changed the query format;
  • a proxy, plugin, or master service returned a different schema;
  • the captured fixture or manually supplied response was damaged.

Do not weaken buffer bounds or header validation to make one packet pass. Reproduce with debug mode, compare multiple servers, and add a fixture-backed regression test for a confirmed format change.

Basic status works but details are missing

Player lists, teams, rules, and extended metadata are not universal. Their availability depends on the protocol family, game version, server settings, and sometimes a separate request.

  • Source servers can disable or reject the optional player and rules queries. Confirm that query_players and query_rules were not set to false.
  • GameSpy, Quake, Unreal, and other older query formats expose different field sets for each game; use normalized fields only where the selected class defines a mapping.
  • Some servers deliberately hide players or return an empty list while still answering their basic status query.
  • TeamSpeak and other voice servers may apply allowlists, permissions, flood limits, or visibility rules to their query interface.

Inspect the protocol-native result before assuming that a normalized field should exist. See understanding results.

Socket creation or write failure

Socket failures are normally routing, firewall, resource-limit, DNS, or transport problems. Confirm:

  • outbound UDP/TCP is permitted from PHP;
  • the response route is permitted back;
  • the host has free file descriptors and ephemeral ports;
  • DNS resolution works inside the actual runtime;
  • IPv6 literals use [address]:port syntax;
  • SELinux, AppArmor, container policy, or hosting restrictions do not deny sockets.

Shared hosting providers frequently block arbitrary outbound UDP even when outbound HTTP works.

TeamSpeak query fails

TeamSpeak requires both ports:

'host' => '192.0.2.10:9987',
'options' => ['query_port' => 10011],

The first is the virtual server's client port. The second is the query service. Also verify the query service's allowlist and flood limits.

HTTP or master-backed protocol fails

Unlike direct Source, GameSpy, Quake, Unreal, Frostbite, or voice-server queries, an HTTP-, plugin-, or master-backed implementation can depend on another endpoint or public listing. Check its entry in protocol options, then verify:

  • the required API, web feed, query plugin, or master service is enabled;
  • the configured web/query port is reachable from PHP;
  • the server appears in a required public listing;
  • credentials and plugin versions match the server configuration;
  • the service returns its expected HTTP status and response format.

Test from the PHP host, not from a workstation on another network.

Timeouts on large lists

Reduce max_servers_per_batch, move the query into a worker, and cache results. Raising every timeout can make a web request much slower without making blocked servers respond. See performance.

Capturing a reproducible fixture

For protocol development, use the fixture generator. Packet captures can contain private or identifying data. Redact only after retaining a private exact copy for diagnosis, and never publish credentials.

Reporting an issue

Include:

  • GameQ version and PHP version;
  • server type and public test address, if disclosure is allowed;
  • client and query ports;
  • whether the failure is consistent or intermittent;
  • game/server/plugin version and relevant mods;
  • exception class and message;
  • a minimal example;
  • a sanitized fixture when licensing and privacy permit it.

Open the report in the fork's issue tracker. Do not post passwords, tokens, administration codes, private master servers, or internal network details.

Clone this wiki locally