keycloak/keycloak · error · Error
resourceId is not found in Location header from request: ${r
Error message
resourceId is not found in Location header from request: ${res.url} What it means
Thrown by the admin-client agent after a `location` header was found, but splitting it on `/` and taking the last segment yields an empty string. This means the Location header is malformed for id extraction (e.g. it ends with a trailing slash or is a bare host), so the agent cannot derive a resource id and surfaces the unexpected shape.
Source
Thrown at js/libs/keycloak-admin-client/src/resources/agent.ts:273
});
// now we get the response of the http request
// if `resourceIdInLocationHeader` is true, we'll get the resourceId from the location header field
// todo: find a better way to find the id in path, maybe some kind of pattern matching
// for now, we simply split the last sub-path of the path returned in location header field
if (returnResourceIdInLocationHeader) {
const locationHeader = res.headers.get("location");
if (typeof locationHeader !== "string") {
throw new Error(
`location header is not found in request: ${res.url}`,
);
}
const resourceId = locationHeader.split(SLASH).pop();
if (!resourceId) {
// throw an error to let users know the response is not expected
throw new Error(
`resourceId is not found in Location header from request: ${res.url}`,
);
}
// return with format {[field]: string}
const { field } = returnResourceIdInLocationHeader;
return { [field]: resourceId };
}
if (
Object.entries(headers || []).find(
([key, value]) =>
key.toLowerCase() === "accept" &&
value === "application/octet-stream",
)
) {
return await res.arrayBuffer();
}View on GitHub (pinned to 66c7e15a37)
Solutions
- Log the raw `location` header value to see its exact shape.
- If the server appends a trailing slash, normalise/proxy-fix so the Location ends with the new id.
- Avoid `returnResourceIdInLocationHeader` for that resource and read the id from the response body if available.
- Report the malformed Location to the backend/proxy owner if it is a regression.
Example fix
// before
return { [field]: locationHeader.split(SLASH).pop() };
// after: tolerate trailing slashes
const trimmed = locationHeader.replace(/\/+$/, '');
const resourceId = trimmed.split(SLASH).pop(); Defensive patterns
Strategy: validation
Validate before calling
function extractResourceId(location: string): string | undefined {
const trimmed = location.replace(/\/+$/, '');
const id = trimmed.split('/').pop();
return id || undefined;
} Type guard
const locationHasTrailingId = (location: string): boolean =>
Boolean(location.replace(/\/+$/, '').split('/').pop()); Try / catch
try {
const { id } = await kcAdminClient.clients.create({ ...payload });
} catch (e) {
if (e instanceof Error && e.message.startsWith('resourceId is not found in Location header')) {
// Location malformed; fall back to listing/lookup
} else throw e;
} Prevention
- Inspect the raw Location value when this fires to spot trailing slashes.
- Fix proxy/server URL normalisation that appends trailing slashes to Location.
- Fall back to body-based id lookup when Location parsing is unreliable.
When it happens
Trigger: The `Location` header is `https://host/realms/master/clients/` (trailing slash), a bare `https://host/`, or otherwise ends in a delimiter; the header points somewhere the naive `split('/').pop()` heuristic cannot parse.
Common situations: Server or proxy normalises URLs and appends a trailing slash; the Location is an external/absolute URL whose last path segment is empty; a routing layer rewrites the Location value.
Related errors
- location header is not found in request: ${res.url}
- Unable to parse response as valid JSON.
- Expected response to have a JSON content type, got '${conten
- Unable to retrieve error message from response, no matching
- Unexpected status = ${status}
AI-assisted analysis of keycloak/keycloak@66c7e15a37 (2026-08-14).
Data as JSON: /api/errors/647a6b256b695e9d.
Report an issue: GitHub.