immich-app/immich · error · BadRequestException
Invalid license key
Error message
Invalid license key
What it means
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.
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.
Example fix
// before
await api.setLicense({ licenseKey: 'ABCD-1234', activationKey: '...' });
// after
await api.setLicense({ licenseKey: 'IMSV-XXXX-XXXX-XXXX-XXXX', activationKey: '...' }); Defensive patterns
Strategy: validation
Validate before calling
if (typeof licenseKey === 'string' && !licenseKey.startsWith('IMSV-')) {
throw new Error('Server license key must start with IMSV-');
} Try / catch
try {
await api.setLicense({ licenseKey, activationKey });
} catch (e) {
if (e.status === 400 && e.message === 'Invalid license key') {
// prompt user to re-enter a valid IMSV- key
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid license key
- Asset dimensions are not available for editing
- assetIds, albumId, or userId is required
- At least two people are required for merging
- Cannot request to join your own cluster group
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/4381698f6964f958.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/server.service.ts:190
sidecar: Object.keys(mimeTypes.sidecar),
};
}
async deleteLicense(): Promise<void> {
await this.systemMetadataRepository.delete(SystemMetadataKey.License);
}
async getLicense(): Promise<LicenseResponseDto> {
const license = await this.systemMetadataRepository.get(SystemMetadataKey.License);
if (!license) {
throw new NotFoundException();
}
return license;
}
async setLicense(dto: LicenseKeyDto): Promise<LicenseResponseDto> {
if (!dto.licenseKey.startsWith('IMSV-')) {
throw new BadRequestException('Invalid license key');
}
const { licensePublicKey } = this.configRepository.getEnv();
const isLicenseValid = this.cryptoRepository.verifySha256(
dto.licenseKey,
dto.activationKey,
licensePublicKey.server,
);
if (!isLicenseValid) {
throw new BadRequestException('Invalid license key');
}
const licenseData = { ...dto, activatedAt: new Date() };
await this.systemMetadataRepository.set(SystemMetadataKey.License, licenseData);
return licenseData;
}
}View on GitHub (pinned to e55ac299a4)