{"record":{"id":"2bca211e652cc2fe","repo":"immich-app/immich","slug":"missing-jwt-token","errorCode":null,"errorMessage":"Missing JWT Token","messagePattern":"Missing JWT Token","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"server/src/maintenance/maintenance-worker.service.ts","lineNumber":262,"sourceCode":"    return this.login(jwtToken);\n  }\n\n  async status(potentiallyJwt?: string): Promise<MaintenanceStatusResponseDto> {\n    try {\n      await this.login(potentiallyJwt);\n      return this.getStatus();\n    } catch {\n      return this.getPublicStatus();\n    }\n  }\n\n  detectPriorInstall(): Promise<MaintenanceDetectInstallResponseDto> {\n    return detectPriorInstall(this.storageRepository);\n  }\n\n  async login(jwt?: string): Promise<MaintenanceAuthDto> {\n    if (!jwt) {\n      throw new UnauthorizedException('Missing JWT Token');\n    }\n\n    try {\n      const result = await jwtVerify<MaintenanceAuthDto>(jwt, new TextEncoder().encode(this.secret));\n      return result.payload;\n    } catch {\n      throw new UnauthorizedException('Invalid JWT Token');\n    }\n  }\n\n  async setAction(action: SetMaintenanceModeDto) {\n    this.setStatus({\n      active: true,\n      action: action.action,\n    });\n\n    await this.runAction(action);\n  }","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/maintenance/maintenance-worker.service.ts#L244-L280","documentation":"The maintenance worker login(jwt?) requires a JWT; if the caller provides none it throws UnauthorizedException('Missing JWT Token'). This is the maintenance-mode auth entry: callers must supply the maintenance JWT (obtained out-of-band or via token login) to perform further maintenance actions.","triggerScenarios":"Calling POST /maintenance/login (or the worker login) with no Authorization header / no JWT argument at all.","commonSituations":"Operator connects to the maintenance API without copying the token; a client strips the auth header; cookie-based session expired and no JWT fallback supplied.","solutions":["Provide the maintenance JWT in the request (typically Authorization: Bearer <jwt>).","Obtain a fresh maintenance token through the documented bootstrap flow before calling login.","Ensure any proxy/gateway in front forwards the Authorization header unchanged."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!jwt) {\n  throw new Error('Maintenance JWT is required');\n}\nawait fetch(`${baseUrl}/maintenance/login`, {\n  method: 'POST',\n  headers: { Authorization: `Bearer ${jwt}` },\n});","typeGuard":"const hasJwt = (headers: Record<string,string>): boolean =>\n  Boolean(headers['Authorization'] || headers['authorization']);","tryCatchPattern":"try {\n  await login(jwt);\n} catch (e) {\n  if ((e as Error).status === 401 && /Missing JWT/.test((e as Error).message)) {\n    // prompt operator for the maintenance token\n  } else throw e;\n}","preventionTips":["Always supply the maintenance JWT as a Bearer token.","Verify the Authorization header survives any proxy in front of the server.","Obtain the token via the documented bootstrap before scripting maintenance."],"tags":["maintenance","authentication","jwt","authorization"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}