API Key plugin is always returning a KEY_NOT_FOUND error

I've got some basic Hono middleware to check API keys:
app.use("*", async (c, next) => {
const { error, key } = await auth.api.verifyApiKey({
body: {
key: "<key>",
},
});
if (error || !key) {
return c.json(
{ error: error?.message || error?.code || "UNKNOWN_API_KEY_ERROR" },
401
);
}

c.set("userId", key.userId);
return next();
});
app.use("*", async (c, next) => {
const { error, key } = await auth.api.verifyApiKey({
body: {
key: "<key>",
},
});
if (error || !key) {
return c.json(
{ error: error?.message || error?.code || "UNKNOWN_API_KEY_ERROR" },
401
);
}

c.set("userId", key.userId);
return next();
});
I'm always getting a KEY_NOT_FOUND error, even when the key's valid. How should I fix this? I've already run all migrations for the DB.
Solution:
Here's the fix, for those interested: ```diff apiKey({ customKeyGenerator: async () => { return crypto.randomUUID();...
Jump to solution
3 Replies
!skyfall
!skyfallOP3d ago
GitHub
GitHub - SkyfallWasTaken/quackatime: A self-hostable time tracking ...
A self-hostable time tracking server for WakaTime. - SkyfallWasTaken/quackatime
GitHub
quackatime/src/routes/api/index.ts at main · SkyfallWasTaken/quack...
A self-hostable time tracking server for WakaTime. - SkyfallWasTaken/quackatime
!skyfall
!skyfallOP3d ago
And here's the full error that Better Auth returns:
{ message: 'Invalid API key.', code: 'KEY_NOT_FOUND' }
{ message: 'Invalid API key.', code: 'KEY_NOT_FOUND' }
Strangely enough, I get the same error even if I create an API key and use it straight after:
const { key: key1 } = await auth.api.createApiKey({
body: {
userId: "8tNfVAUgtAMz0KnGMpNVoJbXaN3T0xnZ",
},
});

console.log("Key 1:", JSON.stringify(key1));

const { error, key } = await auth.api.verifyApiKey({
body: {
key: key1,
},
});
const { key: key1 } = await auth.api.createApiKey({
body: {
userId: "8tNfVAUgtAMz0KnGMpNVoJbXaN3T0xnZ",
},
});

console.log("Key 1:", JSON.stringify(key1));

const { error, key } = await auth.api.verifyApiKey({
body: {
key: key1,
},
});
Looks like I'm triggering this check
// if the key is shorter than the default key length, than we know the key is invalid.
// we can't check if the key is exactly equal to the default key length, because
// a prefix may be added to the key.
+ console.log("Oops!")
return ctx.json({
valid: false,
error: {
message: ERROR_CODES.INVALID_API_KEY,
code: "KEY_NOT_FOUND" as const,
},
key: null,
});
// if the key is shorter than the default key length, than we know the key is invalid.
// we can't check if the key is exactly equal to the default key length, because
// a prefix may be added to the key.
+ console.log("Oops!")
return ctx.json({
valid: false,
error: {
message: ERROR_CODES.INVALID_API_KEY,
code: "KEY_NOT_FOUND" as const,
},
key: null,
});
Solution
!skyfall
!skyfall3d ago
Here's the fix, for those interested:
apiKey({
customKeyGenerator: async () => {
return crypto.randomUUID();
},
+ defaultKeyLength: 32,
}),
apiKey({
customKeyGenerator: async () => {
return crypto.randomUUID();
},
+ defaultKeyLength: 32,
}),

Did you find this page helpful?