immich-app/immich · error · Error
Hostname did not match any listed in methods[].allowedHosts
Error message
Hostname did not match any listed in methods[].allowedHosts in the plugin manifest
What it means
A plain Error thrown by the httpRequest host function when the requested URL's hostname does not match any regex pattern derived from the step's methods[].allowedHosts list. Each allowedHosts entry is converted to a regex ('.' -> '\.', '*' -> '.*') and tested against the URL hostname; if none match, the request is blocked as a security boundary.
Source
Thrown at server/src/services/workflow-execution.service.ts:107
]
>(async (authDto, context, args) => {
const hostname = new URL(args[0]).hostname;
for (const pattern of context.allowedHosts) {
const regex = new RegExp(pattern.replaceAll('.', String.raw`\.`).replaceAll('*', '.*'));
if (regex.test(hostname)) {
// eslint-disable-next-line unicorn/no-invalid-argument-count
const res = await fetch(...args);
return {
ok: res.ok,
status: res.status,
body: await res.text(),
};
}
}
throw new Error('Hostname did not match any listed in methods[].allowedHosts in the plugin manifest');
});
const functions = {
searchAlbums,
createAlbum,
addAssetsToAlbum,
addAssetsToAlbums,
httpRequest,
};
const stubs: typeof functions = {
searchAlbums: dummy,
createAlbum: dummy,
addAssetsToAlbum: dummy,
addAssetsToAlbums: dummy,
httpRequest: dummy,
};
View on GitHub (pinned to 199723261c)
Solutions
- Add the target hostname (or a matching wildcard like '*.example.com') to methods[].allowedHosts in the plugin manifest and re-import.
- Verify the regex translation: '*' becomes '.*' and '.' becomes a literal dot, so write allowedHosts accordingly.
- Prefer the narrowest matching pattern (e.g., 'api.example.com') over broad wildcards.
- After editing the manifest, force plugin re-import by changing its hash or restarting microservices.
Example fix
// before (manifest.json)
{ "methods": [{ "name": "fetchWeather", "allowedHosts": ["weather.io"] }] }
// plugin calls https://api.weather.io/... -> blocked
// after
{ "methods": [{ "name": "fetchWeather", "allowedHosts": ["*.weather.io"] }] } Defensive patterns
Strategy: validation
Validate before calling
function isHostAllowed(url, allowedHosts) {
const host = new URL(url).hostname;
return allowedHosts.some((pattern) => {
const re = new RegExp(pattern.replaceAll('.', '\\.').replaceAll('*', '.*'));
return re.test(host);
});
}
if (!isHostAllowed(targetUrl, manifest.methods[0].allowedHosts)) {
return { ok: false, reason: 'Host not in allowedHosts' };
} Type guard
const isAllowedHostsError = (e: unknown): boolean =>
typeof e === 'object' && e !== null && typeof (e as any).message === 'string' &&
(e as any).message.includes('allowedHosts'); Try / catch
// Surfaces inside httpRequest; validate host before the plugin calls it
if (!isHostAllowed(url, ctx.allowedHosts)) {
return { ok: false, status: 0, body: 'blocked by allowedHosts' };
} Prevention
- List every hostname (or '*.domain' wildcard) the plugin will call in allowedHosts.
- Mirror the server's regex translation when designing patterns.
- Re-import the plugin after editing allowedHosts.
When it happens
Trigger: A plugin calls httpRequest('https://api.example.com/...') but the method's allowedHosts in the manifest omits 'example.com' or lists a different domain. Wildcard patterns that do not cover the subdomain also fail.
Common situations: Plugin author lists allowedHosts but forgets a subdomain; wildcard '*.example.com' is expected but the pattern is written as 'example.com' (no wildcard); plugin switched to a different API host without updating the manifest; typo in the host entry.
Related errors
- Plugin not found
- Calling host functions is not allowed without setting method
- authToken is required
- Invalid token: missing userId
- Invalid token
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/ccd9c4f71ee22acb.
Report an issue: GitHub.