This reference documents every error value, panic condition, HTTP status code, and noteworthy edge-case behavior you may encounter while using GoKit. Each section maps a specific situation to the exact error message, exported sentinel error, or runtime behavior produced by the library so you can handle or debug it confidently.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/AndresGT/GoKit/llms.txt
Use this file to discover all available pages before exploring further.
JWT errors and panics
jwt.Configure validates its input immediately and panics on misconfiguration so problems surface at startup rather than at runtime. Token generation and validation return typed errors that you can inspect or compare with errors.Is.
| Situation | Error / Behavior |
|---|---|
jwt.Configure called with empty Secret | panic: jwt: secret is required |
jwt.Configure called with Secret shorter than 32 characters | panic: jwt: secret must be at least 32 characters |
jwt.Generate (or GeneratePair) called before Configure | error: jwt: not configured, call Configure() first |
| Token signature does not match the secret | jwt.Validate returns an error from the underlying JWT library |
Token has expired (exp claim is in the past) | jwt.Validate returns an error |
Issuer in the token does not match the configured Issuer | error: jwt: invalid issuer |
Signing algorithm in the token header does not match SigningMethod | error: unexpected signing method: <alg> |
Token is not yet active (nbf claim is in the future) | error: jwt: token not active yet |
jwt.MustGenerate fails for any reason | panic (re-panics the underlying error) |
Hash errors
hash.Hash validates the password before hashing it and returns a descriptive error for every validation failure. hash.Verify detects the algorithm from the stored hash prefix and returns an error if the format is unrecognized.
| Situation | Error / Behavior |
|---|---|
Password passed to hash.Hash is an empty string | error: password cannot be empty |
Password length is below MinLength (default 8) | error: password must be at least N characters |
Password length exceeds MaxLength (default 128) | error: password must be at most N characters |
hash.Verify called with a hash whose prefix is not $2a$, $2b$, $2y$, or $argon2id$ | error: unknown hash algorithm |
hash.Verify called with a malformed Argon2 hash (wrong number of $-delimited segments) | error: invalid argon2 hash format |
Middleware auth errors
middleware.Auth extracts and validates the JWT on every non-skipped request. On failure it calls the configured ErrorHandler if one is set, or returns a JSON response with the status codes and body shown below.
| Situation | HTTP Status | Sentinel error |
|---|---|---|
No token in Authorization header or token cookie | 401 Unauthorized | middleware.ErrNoToken |
| Token present but invalid, expired, or signature mismatch | 401 Unauthorized | middleware.ErrInvalidToken |
Token valid but UserID is uuid.Nil or Role is empty | 403 Forbidden | middleware.ErrInvalidClaims |
Token valid and claims non-empty, but role not in RequireRole allowlist | 403 Forbidden | gin.H{"error": "forbidden"} (no sentinel) |
You can replace all of the above with your own response shape by supplying an
ErrorHandler in AuthConfig:CORS panic
| Situation | Behavior |
|---|---|
AllowCredentials: true combined with AllowOrigins: ["*"] | panic: CORS config error: AllowCredentials=true cannot be used with AllowOrigins="*" |
router.Use(middleware.CORS(...)) is called), not at the first request. The combination is forbidden by the Fetch specification — browsers ignore Access-Control-Allow-Credentials: true when the origin is a wildcard.
Logger behaviors
| Situation | Behavior |
|---|---|
Any Fatal-level log is written | Writes the log entry to all configured writers, then calls os.Exit(1) |
DBWriter.Write is called while the internal queue is at capacity | Returns error: log queue full immediately (non-blocking); the entry is dropped |
logger.DisableLogs() is called | Sets MinLevel to OffLevel; no further entries are written until EnableLogs() is called |
logger.InitGlobal is called more than once | The second (and all subsequent) calls are silently ignored — the global logger is initialized with sync.Once |
Common questions
Why does my server panic on startup?
Why does my server panic on startup?
Two GoKit configurations cause panics at startup:
- JWT secret too short.
jwt.Configurepanics ifSecretis empty or fewer than 32 characters. Check the value you are passing — a common mistake is using an environment variable that is unset in a particular deployment.
- CORS credentials with wildcard origin.
middleware.CORSpanics if you setAllowCredentials: truealongsideAllowOrigins: ["*"]. Use explicit origin lists when credentials are required:
My token is valid but the Auth middleware returns 403
My token is valid but the Auth middleware returns 403
A 403 from A 401 means the token is invalid or expired; a 403 means the token is structurally fine but the payload is incomplete. They are intentionally different status codes so you can distinguish them in client-side error handling.
middleware.Auth means the token itself is cryptographically valid and not expired, but the claims inside the token are empty or missing. Specifically, middleware.Auth returns ErrInvalidClaims (HTTP 403) when either UserID equals uuid.Nil or Role is an empty string.Check the call that generated the token:How do I test handlers that use middleware.GetUserID?
How do I test handlers that use middleware.GetUserID?
In unit tests, set the GoKit context keys directly on the The three context keys GoKit uses are:
Setting these manually bypasses
*gin.Context before calling the handler. The keys are unexported constants but their string values are stable:| Key | Type | Set by |
|---|---|---|
"gokit:user_id" | uuid.UUID | middleware.Auth |
"gokit:user_role" | string | middleware.Auth |
"gokit:claims" | *jwt.Claims | middleware.Auth |
middleware.Auth entirely, which is the correct approach for handler-level unit tests — you test the handler logic in isolation without needing a real JWT.Can I use GoKit's logger without Gin?
Can I use GoKit's logger without Gin?
Yes. The core logger is completely independent of Gin. The following functions and types work in any Go program:The only parts that require Gin are:
| Function | Requires Gin |
|---|---|
logger.GinMiddleware() | ✅ |
logger.GetLogger(c) | ✅ |
logger.RegisterRoute / RegisterRoutes | ✅ |
logger.LogRequestInfo / LogRequestWarn / etc. | ✅ |
| Everything else | ❌ |