phalcon/cphalcon · error · Phalcon\Mvc\Router\Exceptions\UnknownHttpMethod
Unknown HTTP method '{method}' in route config
Error message
Unknown HTTP method '{method}' in route config What it means
Each config['routes'] entry may specify an HTTP method that selects which router add* helper is used (addGet, addPost, addPut, ...). After strtolower(), the value must be one of: connect, delete, get, head, options, patch, post, purge, put, trace, or empty (generic add). Any other string throws UnknownHttpMethod with the offending value interpolated into the message.
Source
Thrown at phalcon/Mvc/Router.zep:2089
}
switch method {
case "":
case "connect":
case "delete":
case "get":
case "head":
case "options":
case "patch":
case "post":
case "purge":
case "put":
case "trace":
let methodClass = "add" . ucfirst(method);
let route = this->{methodClass}(pattern, paths);
break;
default:
throw new UnknownHttpMethod(method);
}
if isset routeData["name"] {
route->setName((string) routeData["name"]);
}
if isset routeData["hostname"] {
route->setHostname((string) routeData["hostname"]);
}
}
protected function extractRealUri( string uri) -> string
{
var urlParts, realUri;
let urlParts = explode("?", uri, 2),
realUri = urlParts[0];
return realUri;View on GitHub (pinned to b7419de9cd)
Solutions
- Use one of the supported verbs (case-insensitive): connect, delete, get, head, options, patch, post, purge, put, trace
- Omit 'method' entirely (or set null) for a method-agnostic route
- Trim and normalize input if methods come from user data: strtolower(trim($method))
Example fix
// before
{
"routes": [
{
"pattern": "/api/users",
"paths": {"controller": "users", "action": "index"},
"method": "ANY"
}
]
}
// after
{
"routes": [
{
"pattern": "/api/users",
"paths": {"controller": "users", "action": "index"}
}
]
} Defensive patterns
Strategy: validation
Validate before calling
// whitelist methods before they reach the router
const ALLOWED = ['', 'connect', 'delete', 'get', 'head', 'options', 'patch', 'post', 'purge', 'put', 'trace'];
foreach ($config['routes'] ?? [] as $i => $entry) {
if (isset($entry['method'])) {
$method = strtolower(trim((string) $entry['method']));
if (!in_array($method, ALLOWED, true)) {
throw new InvalidArgumentException("routes[$i]: unsupported HTTP method '{$entry['method']}'");
}
$config['routes'][$i]['method'] = $method;
}
}
$router->loadFromConfig($config); Type guard
function isSupportedHttpMethod(mixed $method): bool
{
if ($method === null) {
return true;
}
$allowed = ['connect', 'delete', 'get', 'head', 'options', 'patch', 'post', 'purge', 'put', 'trace', ''];
return is_string($method) && in_array(strtolower(trim($method)), $allowed, true);
} Try / catch
try {
$router->loadFromConfig($config);
} catch (\Phalcon\Mvc\Router\Exceptions\UnknownHttpMethod $e) {
$logger->error('Bad HTTP method in route config: ' . $e->getMessage());
throw $e;
} Prevention
- There is no 'ANY' method — omit the key for method-agnostic routes
- Trim and lowercase method values from external sources before validation
- Document the exact verb list (connect, delete, get, head, options, patch, post, purge, put, trace) next to your routes schema
When it happens
Trigger: "method": "LIST" or "FETCH" for a custom verb; typos like "post ", "Getx", "postt"; "method": "any" or "*" expecting a match-all route; uppercase is fine (strtolower is applied) but whitespace and unknown words are not.
Common situations: Copying method lists from another framework that accepts 'ANY'; custom API verbs; trailing whitespace from spreadsheet/CSV exports; locale variants like 'POST'.
Related errors
- loadFromConfig requires an array or Phalcon\Config\ConfigInt
- 'defaults' must be an array
- 'routes' must be an array
- 'groups' must be an array
- Route config entry is missing 'pattern'
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/5c50ea1c69a59111.
Report an issue: GitHub.