{"record":{"id":"4381698f6964f958","repo":"immich-app/immich","slug":"invalid-license-key","errorCode":null,"errorMessage":"Invalid license key","messagePattern":"Invalid license key","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/server.service.ts","lineNumber":190,"sourceCode":"      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\n    const licenseData = { ...dto, activatedAt: new Date() };\n\n    await this.systemMetadataRepository.set(SystemMetadataKey.License, licenseData);\n\n    return licenseData;\n  }\n}","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/services/server.service.ts#L172-L208","documentation":"setLicense validates the license key format before cryptographic verification. Immich server license keys must begin with the 'IMSV-' prefix; a key without that prefix is rejected immediately with this BadRequestException before any signature check happens.","triggerScenarios":"Calling the license activation endpoint (PUT /server/license via setLicense) with a dto.licenseKey that does not start with 'IMSV-', e.g. a truncated key, a key from Immich Mobile ('IMSM-') instead of server, or a free-form string.","commonSituations":"Copying the wrong license key from the purchase email (mobile vs server license), pasting with missing characters, or migrating an old key format from a previous Immich version.","solutions":["Check the license key starts with 'IMSV-' before calling the API.","Use the server license key (not the mobile 'IMSM-' key) from the purchase email / account page.","Re-copy the key ensuring the full string including prefix and no whitespace.","If the key looks correct but keeps failing, ensure it is paired with the matching activationKey."],"exampleFix":"// before\nawait api.setLicense({ licenseKey: 'ABCD-1234', activationKey: '...' });\n// after\nawait api.setLicense({ licenseKey: 'IMSV-XXXX-XXXX-XXXX-XXXX', activationKey: '...' });","handlingStrategy":"validation","validationCode":"if (typeof licenseKey === 'string' && !licenseKey.startsWith('IMSV-')) {\n  throw new Error('Server license key must start with IMSV-');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await api.setLicense({ licenseKey, activationKey });\n} catch (e) {\n  if (e.status === 400 && e.message === 'Invalid license key') {\n    // prompt user to re-enter a valid IMSV- key\n  }\n}","preventionTips":["Validate the IMSV- prefix in the form before submit.","Distinguish server (IMSV-) from mobile (IMSM-) keys in the UI.","Trim pasted values to avoid whitespace corruption."],"tags":["license","validation","bad-request","api"],"backgroundTag":"invalid-argument-format","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}