{"record":{"id":"7a68d6140de627ee","repo":"immich-app/immich","slug":"not-found-7a68d6","errorCode":null,"errorMessage":"Not Found","messagePattern":"Not Found","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"info","filePath":"server/src/services/server.service.ts","lineNumber":182,"sourceCode":"    return serverStats;\n  }\n\n  getSupportedMediaTypes(): ServerMediaTypesResponseDto {\n    return {\n      video: Object.keys(mimeTypes.video),\n      image: Object.keys(mimeTypes.image),\n      sidecar: Object.keys(mimeTypes.sidecar),\n    };\n  }\n\n  async deleteLicense(): Promise<void> {\n    await this.systemMetadataRepository.delete(SystemMetadataKey.License);\n  }\n\n  async getLicense(): Promise<LicenseResponseDto> {\n    const license = await this.systemMetadataRepository.get(SystemMetadataKey.License);\n    if (!license) {\n      throw new NotFoundException();\n    }\n    return license;\n  }\n\n  async setLicense(dto: LicenseKeyDto): Promise<LicenseResponseDto> {\n    if (!dto.licenseKey.startsWith('IMSV-')) {\n      throw new BadRequestException('Invalid license key');\n    }\n    const { licensePublicKey } = this.configRepository.getEnv();\n    const isLicenseValid = this.cryptoRepository.verifySha256(\n      dto.licenseKey,\n      dto.activationKey,\n      licensePublicKey.server,\n    );\n    if (!isLicenseValid) {\n      throw new BadRequestException('Invalid license key');\n    }\n","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/server.service.ts#L164-L200","documentation":"Thrown by ServerService.getLicense when systemMetadataRepository.get(SystemMetadataKey.License) returns null. The server has no license key stored in system metadata. NotFoundException with no message -> HTTP 404 'Not Found'. Used by the license check endpoint to signal 'no license configured'.","triggerScenarios":"GET /server/license (or the license-view endpoint) on a server that has never had a license set, or whose license was deleted via deleteLicense.","commonSituations":"Fresh install; admin cleared the license; license was set on a different instance; checking license status before activation.","solutions":["Activate a license via POST/PUT /server/license (setLicense) before querying it.","Treat 404 from this endpoint as 'no license configured' (not an error) in the client.","Add a message to the NotFoundException so clients can distinguish from a generic 404."],"exampleFix":"// before\nconst license = await this.systemMetadataRepository.get(SystemMetadataKey.License);\nif (!license) {\n  throw new NotFoundException();\n}\n\n// after\nconst license = await this.systemMetadataRepository.get(SystemMetadataKey.License);\nif (!license) {\n  throw new NotFoundException('No license configured');\n}\n\n// client-side\ntry {\n  return await api.get('/server/license');\n} catch (e) {\n  if (e.status === 404) return null; // no license set\n  throw e;\n}","handlingStrategy":"validation","validationCode":"// Check whether a license is configured before reading it.\nconst license = await systemMetadataRepository.get(SystemMetadataKey.License).catch(() => null);\nif (!license) {\n  // no license configured; prompt admin to activate one\n  return null;\n}\nreturn license;","typeGuard":"const hasLicense = (l: LicenseResponseDto | null | undefined): l is LicenseResponseDto =>\n  !!l && typeof l.licenseKey === 'string';","tryCatchPattern":"try {\n  return await serverService.getLicense();\n} catch (e) {\n  if (e instanceof NotFoundException) {\n    // no license configured yet; not an error\n    return null;\n  }\n  throw e;\n}","preventionTips":["Treat 404 from the license endpoint as 'no license set', not as a failure.","Add a message to the NotFoundException for client-friendly semantics.","Check license status before showing licensed features in the UI."],"tags":["server","license","not-found","nestjs","administration"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}