walkor/workerman · error · RuntimeException
Bad worker->transport ${var_export($this->transport, true)}
Error message
Bad worker->transport ${var_export($this->transport, true)} What it means
When the socketName uses a non-builtin scheme (a custom protocol class), parseSocketAddress() also validates $worker->transport against Worker::BUILD_IN_TRANSPORTS = ['tcp','udp','unix','ssl']. An unknown transport value throws this exception with the var_export'd value, because the transport decides which low-level socket gets created (BUILD_IN_TRANSPORTS[$this->transport] . ':' . $address would otherwise index a missing key).
Source
Thrown at src/Worker.php:2574
// Get the application layer communication protocol and listening address.
[$scheme, $address] = explode(':', $this->socketName, 2);
// Check application layer protocol class.
if (!isset(self::BUILD_IN_TRANSPORTS[$scheme])) {
// Validate scheme contains only safe characters for class name resolution.
if (!preg_match('/^[a-zA-Z][a-zA-Z0-9]*$/', $scheme)) {
throw new RuntimeException("Invalid protocol scheme '$scheme'");
}
$scheme = ucfirst($scheme);
$this->protocol = 'Protocols\\' . $scheme;
if (!class_exists($this->protocol)) {
$this->protocol = "Workerman\\Protocols\\$scheme";
if (!class_exists($this->protocol)) {
throw new RuntimeException("class \\Protocols\\$scheme not exist");
}
}
if (!isset(self::BUILD_IN_TRANSPORTS[$this->transport])) {
throw new RuntimeException('Bad worker->transport ' . var_export($this->transport, true));
}
} else if ($this->transport === 'tcp') {
$this->transport = $scheme;
}
//local socket
return self::BUILD_IN_TRANSPORTS[$this->transport] . ":" . $address;
}
/**
* Pause accept new connections.
*
* @return void
*/
public function pauseAccept(): void
{
if (static::$globalEvent !== null && !$this->pauseAccept && $this->mainSocket !== null) {
static::$globalEvent->offReadable($this->mainSocket);
$this->pauseAccept = true;View on GitHub (pinned to 1391112a61)
Solutions
- Set the transport to a legal value: `$worker->transport = 'tcp';` (use 'udp', 'unix', or 'ssl' as appropriate).
- If you wanted websocket/http, drop the custom transport and put it in the listen address instead: `new Worker('ws://0.0.0.0:8080')` or `new Worker('http://0.0.0.0:8080')`.
- For TLS with a custom text protocol, keep transport='ssl' and configure $worker->transport context with local_cert/local_pk.
- If the transport comes from config, validate/case-normalize it before assigning.
Example fix
// before: 'websocket' is not a transport
$worker = new Worker('myProto://0.0.0.0:8080');
$worker->transport = 'websocket';
// after: keep the transport low-level; express the protocol in the scheme
$worker = new Worker('MyProto://0.0.0.0:8080');
$worker->transport = 'tcp'; Defensive patterns
Strategy: validation
Validate before calling
$transport = strtolower((string)$config['transport']);
if (!in_array($transport, array_keys(Workerman\Worker::BUILD_IN_TRANSPORTS), true)) {
throw new InvalidArgumentException(
"transport must be one of tcp|udp|unix|ssl, got '{$config['transport']}'"
);
}
$worker->transport = $transport; Type guard
function isBuiltinTransport(string $transport): bool
{
return isset(Workerman\Worker::BUILD_IN_TRANSPORTS[$transport]);
} Prevention
- Remember transport is only tcp/udp/unix/ssl; protocols like websocket/http belong in the listen scheme (ws://, http://).
- Validate any transport value coming from env/config before assigning it to the worker.
When it happens
Trigger: Setting $worker->transport to anything outside tcp/udp/unix/ssl while using a custom scheme — e.g. $worker->transport = 'websocket' (not a transport; the scheme 'ws://' handles that), 'tcp6', 'http', 'Text', or null/int from a config variable.
Common situations: Confusing the application-layer protocol with the transport: writing transport='websocket' or 'http' instead of using the ws:// or http:// scheme in the listen address; loading transport from an env/config file with a typo or wrong casing; upgrading old configs that used arbitrary strings.
Related errors
- ${errMsg}
- Invalid protocol scheme '$scheme'
- Bad remoteAddress
- Invalid protocol scheme '$scheme'
- class \Protocols\$scheme not exist
AI-assisted analysis of walkor/workerman@1391112a61 (2026-08-21).
Data as JSON: /api/errors/f2e735f2640aa43f.
Report an issue: GitHub.