immich-app/immich · error · NotAcceptableException
The route was requested as , but only returns text/html
Error message
The route ${request.path} was requested as ${request.header('accept')}, but only returns text/html What it means
Raised by the SSR middleware in ApiService when a non-/api GET/HEAD request negotiates a response type other than text/html (request.accepts('text/html') is falsy). The server-rendered web client can only serve HTML, so clients asking for JSON or another content type on a web route get this error instead of the SPA index. The inputs at fault are the request's path and Accept header.
Solutions
- Send Accept: text/html (or */*) when fetching web routes
- Use the /api-prefixed REST endpoints for machine-readable responses
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at server/src/services/api.service.ts:61 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/c3502b882068f7da.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/api.service.ts:61
try {
index = readFileSync(resourcePaths.web.indexHtml).toString();
} catch {
this.logger.warn(`Unable to open ${resourcePaths.web.indexHtml}, skipping SSR.`);
}
return async (request: Request, res: Response, next: NextFunction) => {
const method = request.method.toLowerCase();
if (
request.url.startsWith('/api') ||
(method !== 'get' && method !== 'head') ||
excludePaths.some((item) => request.url.startsWith(item))
) {
return next();
}
const responseType = request.accepts('text/html');
if (!responseType) {
throw new NotAcceptableException(
`The route ${request.path} was requested as ${request.header('accept')}, but only returns text/html`,
);
}
let status = 200;
let html = index;
const defaultDomain = request.host ? `${request.protocol}://${request.host}` : undefined;
let meta: OpenGraphTags | null = null;
const shareKey = request.url.match(/^\/share\/(.+)$/);
if (shareKey) {
try {
const key = shareKey[1];
const auth = await this.authService.validateSharedLinkKey(key);
meta = await this.sharedLinkService.getMetadataTags(auth, defaultDomain);
} catch {View on GitHub (pinned to e55ac299a4)