ratchetphp/Ratchet · error · UnexpectedValueException

Invalid Port

Error message

Invalid Port

What it means

FlashPolicy::addAllowedAccess() validates the $ports value via validatePorts() after the domain check. An invalid port spec throws UnexpectedValueException('Invalid Port'). Valid values are '*' (any port), a single numeric port like '843', or a comma-separated list such as '80,443'; anything else (ranges like '1-1024', negative numbers, non-numeric text, empty strings) is rejected because Flash cross-domain policies only support enumerated ports or a blanket wildcard.

Solutions

  1. Use '*' for all ports, or enumerate them as a comma-separated list of plain numbers, e.g. '80,443,843'.
  2. Convert any range from config into explicit ports before calling addAllowedAccess (expand '5000-5002' to '5000,5001,5002').
  3. Cast strictly numeric values to string and trim whitespace so stray spaces or type juggling do not fail validation.
  4. Remember Flash policy files only ever grant access on the policy port (843) or explicitly listed ports; drop ports you cannot serve.

Example fix

// before
$fp->addAllowedAccess('example.com', '1000-2000');

// after
$fp->addAllowedAccess('example.com', '1000,1001,1002'); // or '*' for all
Defensive patterns

Strategy: validation

Validate before calling

function isValidFlashPolicyPorts($ports): bool {
    if ($ports === '*') return true;
    return (bool) preg_match('/^\d+(,\d+)*$/', (string) $ports);
}
if (!isValidFlashPolicyPorts($ports)) { /* normalize or reject before calling addAllowedAccess */ }

Type guard

function isFlashPortSpec($ports): bool {
    return $ports === '*' || (is_string($ports) && preg_match('/^\d+(,\d+)*$/', $ports) === 1);
}

Try / catch

try {
    $fp->addAllowedAccess($domain, $ports);
} catch (\UnexpectedValueException $e) {
    if ($e->getMessage() === 'Invalid Port') {
        error_log("Rejecting invalid policy port spec: " . var_export($ports, true));
    } else { throw $e; }
}

Prevention

When it happens

Trigger: Passing a port range ('1024-2048') instead of a comma list; passing an integer 0 or a negative number; passing '843,secure' or other non-numeric tokens; passing an empty string instead of '*' when intending all ports.

Common situations: Expressing firewall-style ranges in the policy config because that is how ops teams think about ports; confusing the policy port list with allowed scheme ports; leaving the config value blank expecting the default to behave like '*'.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of ratchetphp/Ratchet@e621c6c40b (2026-09-16). Data as JSON: /api/errors/46f3818750ba104a. Report an issue: GitHub.

Appendix: source

Thrown at src/Ratchet/Server/FlashPolicy.php:66

     * @param string $domain Specifies a requesting domain to be granted access. Both named domains and IP
     * addresses are acceptable values. Subdomains are considered different domains. A wildcard (*) can
     * be used to match all domains when used alone, or multiple domains (subdomains) when used as a
     * prefix for an explicit, second-level domain name separated with a dot (.)
     * @param string $ports A comma-separated list of ports or range of ports that a socket connection
     * is allowed to connect to. A range of ports is specified through a dash (-) between two port numbers.
     * Ranges can be used with individual ports when separated with a comma. A single wildcard (*) can
     * be used to allow all ports.
     * @param bool $secure
     * @throws \UnexpectedValueException
     * @return FlashPolicy
     */
    public function addAllowedAccess($domain, $ports = '*', $secure = false) {
        if (!$this->validateDomain($domain)) {
           throw new \UnexpectedValueException('Invalid domain');
        }

        if (!$this->validatePorts($ports)) {
           throw new \UnexpectedValueException('Invalid Port');
        }

        $this->_access[]   = array($domain, $ports, (bool)$secure);
        $this->_cacheValid = false;

        return $this;
    }
    
    /**
     * Removes all domains from the allowed access list.
     * 
     * @return \Ratchet\Server\FlashPolicy
     */
    public function clearAllowedAccess() {
        $this->_access      = array();
        $this->_cacheValid = false;

        return $this;

View on GitHub (pinned to e621c6c40b)