n8n-io/n8n · critical · NotFoundError

404

404

Error message

Could not find owner for credential "${existingCredential.id}"

What it means

Thrown by CredentialsService.prepareUpdateData when an existing project-scoped credential has no shared row with role 'credential:owner'. Every project credential must have exactly one owner sharing; the absence indicates data corruption (orphaned credential row) — an integrity error, not a normal user mistake.

Source

Thrown at packages/cli/src/credentials/credentials.service.ts:787

			mergedData.data = this.unredact(
				mergedData.data,
				decryptedData,
				this.getCredentialTypeProperties(existingCredential.type),
			);
		}
		if (existingCredential.usageScope === 'instance') {
			await this.validateInstanceCredentialUpdate(
				existingCredential,
				mergedData.data ?? decryptedData,
				undefined,
				options?.operationContext,
			);
		} else {
			const projectOwningCredential = existingCredential.shared?.find(
				(shared) => shared.role === 'credential:owner',
			);
			if (!projectOwningCredential) {
				throw new NotFoundError(`Could not find owner for credential "${existingCredential.id}"`);
			}

			await validateExternalSecretsPermissions({
				user,
				projectId: projectOwningCredential.projectId,
				dataToSave: data.data,
				decryptedExistingData: decryptedData,
			});

			if (this.externalSecretsConfig.externalSecretsForProjects && data.data) {
				await validateAccessToReferencedSecretProviders(
					projectOwningCredential.projectId,
					data.data,
					this.externalSecretsProviderAccessCheckService,
					'update',
				);
			}
		}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Restore the missing owner sharing row in shared_credentials (projectId of the true owner, role 'credential:owner') via admin/DB tooling.
  2. Re-run the ownership repair migration or use the admin API to reassign ownership.
  3. If irreparable, delete the orphaned credential and recreate it.
Defensive patterns

Strategy: try-catch

Validate before calling

// This is a data-integrity error; pre-check the owner sharing exists.
const owner = credential.shared?.find(s => s.role === 'credential:owner');
if (!owner) {
  throw new Error('Orphaned credential — repair the owner sharing before update.');
}

Try / catch

try {
  await service.prepareUpdateData(user, data, existing);
} catch (e) {
  if (/Could not find owner for credential/i.test(e.message)) {
    // page admins: run ownership repair / reassign owner manually
  } else throw e;
}

Prevention

When it happens

Trigger: PATCH /credentials/:id on a project credential whose shared_credentials owner row was deleted or never created (manual DB edit, failed migration, partial cleanup).

Common situations: Direct database manipulation removed the owner sharing. A buggy migration left orphaned credentials. Re-assigning ownership failed midway.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/f4fbaa259c78da24. Report an issue: GitHub.