Skip to content

Authentication Errors

Every error message the Authentication component and its services throw, with cause and fix. See the Overview for initial setup.

  • Startup errors (400 unless noted) come from AuthenticateComponent.binding() and stop the application before it serves traffic.
  • Runtime errors (401) come from request-time credential extraction, verification, or strategy exhaustion.
  • Structural errors (500) come from calling an unsupported operation (e.g. signing on a verify-only service) or accessing uninitialized state.
  • All of them go through getError(), which defaults statusCode to 400 when not given explicitly - so every "startup" error below is a 400 unless the table says otherwise.

AuthenticateComponent (startup)

Thrown during binding() while validating options and wiring services.

MessageStatusCauseFix
[AuthenticateComponent] At least one of jwtOptions or basicOptions must be provided400Neither JWT_OPTIONS nor BASIC_OPTIONS bound before this.component(AuthenticateComponent)Bind at least one before registering the component - see Setup
[AuthenticateComponent] Unknown JOSE standard: {standard}400jwtOptions.standard is not 'JWS' or 'JWKS'Use JOSEStandards.JWS or JOSEStandards.JWKS
[defineJWSAuth] Invalid jwtSecret | Provided: {jwtSecret}400jwtSecret falsy or equals placeholder 'unknown_secret'Set a real secret, e.g. APP_ENV_JWT_SECRET
[defineJWSAuth] getTokenExpiresFn is required400getTokenExpiresFn missing from JWS optionsProvide () => Number(process.env.APP_ENV_JWT_EXPIRES_IN || 86400)
[defineJWKSAuth] keys.private and keys.public are required for issuer mode400Issuer mode missing one or both keysProvide keys.private and keys.public
[defineJWKSAuth] keys.format is required and must be one of: pem, jwk400keys.format missing or invalidUse JWKSKeyFormats.PEM or JWKSKeyFormats.JWK
[defineJWKSAuth] kid is required for issuer mode400kid (Key ID) not providedProvide a unique kid string
[defineJWKSAuth] getTokenExpiresFn is required for issuer mode400getTokenExpiresFn missingProvide a token-expiry function
[defineJWKSAuth] jwksUrl is required for verifier mode400Verifier mode missing jwksUrlProvide the issuer's /certs URL
[defineJWKSAuth] Invalid JWKS mode: {mode}400mode is not 'issuer' or 'verifier'Use JWKSModes.ISSUER or JWKSModes.VERIFIER
[defineBasicAuth] verifyCredentials function is required400BASIC_OPTIONS bound without a verifyCredentials callbackProvide the callback - see Setup
[defineControllers] Auth controller requires jwtOptions to be configured400useAuthController: true but no jwtOptions boundBind JWT_OPTIONS before enabling the auth controller

NOTE

applicationSecret is optional and not validated. The component and every token service treat it as optional - omitting it simply disables AES payload encryption. It is never checked for presence.

Bearer token services (runtime)

Shared by JWSTokenService, JWKSIssuerTokenService, and JWKSVerifierTokenService via AbstractBearerTokenService.

MessageStatusMethodCauseFix
Unauthorized user! Missing authorization header401extractCredentialsNo Authorization headerSend Authorization: Bearer <token>
Unauthorized user! Invalid schema of request token!401extractCredentialsHeader doesn't start with BearerUse the Bearer scheme
Authorization header value is invalid format. It must follow the pattern: 'Bearer xx.yy.zz' ...401extractCredentialsHeader doesn't split into exactly 2 partsCheck for extra whitespace or a malformed token
[verify] Invalid request token!401verifyToken value is emptyEnsure the token half of the header isn't blank
[verify] Invalid or expired token401verifydoVerify() threw - expired, malformed, or bad signatureCheck application logs for the real cause (see below)
[generate] Invalid token payload!401generatePayload is null/undefinedPass a non-null IJWTTokenPayload
[generate] Failed to generate token500generateSigning failed (key/algorithm issue)Check application logs for the real cause

TIP

Errors are sanitized on the wire. verify() and generate() never leak the original error.message to the client. The full error is logged at error level - run grep "Failed to verify token" logs/application.log to find it.

JWSTokenService (constructor)

MessageStatusCauseFix
[JWSTokenService] Invalid jwtSecret500jwtSecret falsy in injected optionsFix the JWT_OPTIONS binding
[JWSTokenService] Invalid getTokenExpiresFn500getTokenExpiresFn falsy in injected optionsFix the JWT_OPTIONS binding
[getSigningKey] Invalid jwtSecret!400jwtSecret Uint8Array is nullShould not happen after constructor validation - report if seen

JWKSIssuerTokenService (init + runtime)

MessageStatusMethodCauseFix
[JWKSIssuerTokenService] Unknown key driver: {driver}500resolveKeyContentkeys.driver not 'text' or 'file'Use JWKSKeyDrivers.TEXT or .FILE
[JWKSIssuerTokenService] Invalid raw.priv key!500parseKeyMaterialResolved private key content is emptyCheck the file path or inline string
[JWKSIssuerTokenService] Invalid raw.pub key!500parseKeyMaterialResolved public key content is emptyCheck the file path or inline string
[JWKSIssuerTokenService] Invalid JWK key material500parseKeyMaterialJWK JSON parse or importJWK() failedValidate the JWK is well-formed JSON (see below)
[JWKSIssuerTokenService] Unknown key format: {format}500parseKeyMaterialkeys.format not 'pem' or 'jwk'Use JWKSKeyFormats.PEM or .JWK
[getSigningKey] Invalid privateKey!400getSigningKeyPrivate key null - init incomplete or failedEnsure initialize() succeeded; check logs
[JWKSIssuerTokenService] JWKS not initialized yet. Call getJWKSAsync() instead.500getJWKSSync getJWKS() called before lazy init completedUse await getJWKSAsync() instead

WARNING

File read errors are not wrapped. With JWKSKeyDrivers.FILE, readFile() errors (ENOENT, EACCES, ...) surface as raw Node.js filesystem errors during initialization - they are not caught and re-thrown as getError().

JWKSVerifierTokenService (runtime)

MessageStatusMethodCause
[JWKSVerifierTokenService] Verifier mode cannot sign tokens500getSignergenerate() called on a verify-only service
[JWKSVerifierTokenService] Verifier mode cannot sign tokens500getSigningKeySigning key accessed on a verify-only service
[JWKSVerifierTokenService] Verifier mode has no token expiry500getDefaultTokenExpiresFnToken expiry accessed on a verify-only service

Fix: token generation must happen on the issuer service. If one application needs both signing and verification, use JWKSModes.ISSUER everywhere - an issuer can both sign and verify.

BasicTokenService (runtime)

MessageStatusMethodCauseFix
[BasicTokenService] Invalid verifyCredentials function500constructorverifyCredentials missing from injected optionsProvide the callback in BASIC_OPTIONS
Unauthorized! Missing authorization header401extractCredentialsNo Authorization headerSend Authorization: Basic <base64>
Unauthorized! Invalid authorization schema, expected Basic401extractCredentialsHeader doesn't start with BasicUse the Basic scheme
Unauthorized! Invalid authorization header format401extractCredentialsHeader doesn't split into exactly 2 partsCheck the header value
Unauthorized! Invalid base64 credentials format401extractCredentialsBase64 decode failed, or no : separator, or empty usernameVerify the client encodes username:password correctly
Unauthorized! Invalid username or password401verifyverifyCredentials callback returned nullExpected on wrong credentials - check your callback's lookup logic if unexpected

AuthenticationStrategyRegistry (startup + runtime)

Inherited from AbstractAuthRegistry.

MessageStatusMethodCauseFix
[getKey] Invalid name | name: {name}400getKeyStrategy name empty or falsyPass a non-empty strategy name
[AuthenticationStrategyRegistry] No items registered400getDefaultNameNo strategies registered yetRegister at least one strategy
[AuthenticationStrategyRegistry] Descriptor not found: {name}400resolveDescriptorRoute references a strategy name that was never registeredRegister it after the component - see below
[AuthenticationStrategyRegistry] Failed to resolve: {name}400resolveDescriptorStrategy registered but the container returned nullCheck the strategy's own constructor dependencies

Fix for "Descriptor not found": strategies are not auto-registered by AuthenticateComponent.

typescript
this.component(AuthenticateComponent);

AuthenticationStrategyRegistry.getInstance().register({
  container: this,
  strategies: [{ name: Authentication.STRATEGY_JWT, strategy: JWSAuthenticationStrategy }],
});

AuthenticationProvider (runtime)

The middleware that executes strategies in the configured mode.

MessageStatusMethodCause
Authentication failed. Tried strategies: {strategies}401executeAnyModeEvery strategy failed in 'any' mode
Failed to identify authenticated user!401executeAllModeAll strategies passed in 'all' mode, but the first strategy's userId is falsy
Invalid authentication mode | mode: {mode}500createAuthenticateMiddlewaremode is not 'any' or 'all'

Fix for "Authentication failed": verify the client sends the right header (Bearer <token> or Basic <base64>); common causes are an expired token, a token signed with a different key, or the wrong strategy name in the route config.

Auth controller factory

MessageStatusMethodCauseFix
[AuthController] Failed to init auth controller | Invalid injectable authentication service!400constructorDI could not resolve the service at controllerOpts.serviceKeyRegister your service before the component
typescript
this.service(AuthenticationService);

this.bind<TAuthenticationRestOptions>({ key: AuthenticateBindingKeys.REST_OPTIONS }).toValue({
  useAuthController: true,
  controllerOpts: { restPath: '/auth', serviceKey: 'services.AuthenticationService' },
});

this.component(AuthenticateComponent);

Error categories

See also