Documentation Index
Fetch the complete documentation index at: https://mintlify.com/auth0/go-auth0/llms.txt
Use this file to discover all available pages before exploring further.
The Auth0 Go SDK provides structured error types for both the Management API and Authentication API. These error types contain detailed information about what went wrong and how to handle different error scenarios.
Authentication API Errors
Error Type
type Error struct {
StatusCode int `json:"statusCode"`
Err string `json:"error"`
Message string `json:"error_description"`
MFAToken string `json:"mfa_token,omitempty"`
}
Represents errors returned from the Authentication API. The Err property can be used to check the error code returned from the API.
Methods
Error
func (a *Error) Error() string
Formats the error into a string representation.
Returns: A formatted string in the format: "<StatusCode> <Err>: <Message>"
Example:
import "github.com/auth0/go-auth0/v2/authentication"
token, err := authAPI.LoginWithPassword(ctx, request)
if err != nil {
if authErr, ok := err.(*authentication.Error); ok {
fmt.Println(authErr.Error())
// Output: "401 invalid_grant: Wrong email or password."
}
}
Status
func (a *Error) Status() int
Returns the status code of the error.
Example:
import "github.com/auth0/go-auth0/v2/authentication"
token, err := authAPI.LoginWithPassword(ctx, request)
if err != nil {
if authErr, ok := err.(*authentication.Error); ok {
statusCode := authErr.Status()
if statusCode == 401 {
// Handle unauthorized error
}
}
}
GetMFAToken
func (a *Error) GetMFAToken() string
Returns the MFA token associated with the error, if any. Returns an empty string if the error is nil or if there is no MFA token.
Example:
import "github.com/auth0/go-auth0/v2/authentication"
token, err := authAPI.LoginWithPassword(ctx, request)
if err != nil {
if authErr, ok := err.(*authentication.Error); ok {
if mfaToken := authErr.GetMFAToken(); mfaToken != "" {
// MFA is required, proceed with MFA flow
fmt.Println("MFA token:", mfaToken)
}
}
}
Common Authentication Error Codes
| Error Code | Description |
|---|
invalid_grant | Wrong email or password, or user is blocked |
invalid_request | Missing required parameter or invalid request format |
unauthorized | Invalid or expired token |
access_denied | User denied authorization |
mfa_required | Multi-factor authentication is required |
invalid_user_password | Password does not meet policy requirements |
password_leaked | Password has been leaked and cannot be used |
Management API Errors
The Management API uses HTTP status code-based error types. All error types embed *core.APIError and contain a Body field with the error details.
BadRequestError (400)
type BadRequestError struct {
*core.APIError
Body interface{}
}
Invalid request URI. The message will vary depending on the cause.
Example:
import "github.com/auth0/go-auth0/v2/management"
client, err := api.Client.Create(ctx, &management.Client{
Name: auth0.String(""), // Empty name
})
if err != nil {
if badReq, ok := err.(*management.BadRequestError); ok {
fmt.Println("Bad request:", badReq.Body)
}
}
UnauthorizedError (401)
type UnauthorizedError struct {
*core.APIError
Body interface{}
}
Invalid token.
Example:
import "github.com/auth0/go-auth0/v2/management"
client, err := api.Client.Read(ctx, clientID)
if err != nil {
if unauth, ok := err.(*management.UnauthorizedError); ok {
// Token is invalid or expired, refresh your token
fmt.Println("Unauthorized:", unauth.Body)
}
}
PaymentRequiredError (402)
type PaymentRequiredError struct {
*core.APIError
Body interface{}
}
A paid subscription is required for this feature.
ForbiddenError (403)
type ForbiddenError struct {
*core.APIError
Body interface{}
}
Insufficient scope. For example: “Insufficient scope, expected: read:actions.”
Example:
import "github.com/auth0/go-auth0/v2/management"
action, err := api.Action.Read(ctx, actionID)
if err != nil {
if forbidden, ok := err.(*management.ForbiddenError); ok {
// Token does not have required scopes
fmt.Println("Forbidden:", forbidden.Body)
}
}
NotFoundError (404)
type NotFoundError struct {
*core.APIError
Body interface{}
}
The requested resource does not exist.
Example:
import "github.com/auth0/go-auth0/v2/management"
client, err := api.Client.Read(ctx, "invalid-id")
if err != nil {
if notFound, ok := err.(*management.NotFoundError); ok {
fmt.Println("Client not found:", notFound.Body)
}
}
ConflictError (409)
type ConflictError struct {
*core.APIError
Body interface{}
}
A resource with the same identifier already exists. For example, an action module with the same name.
Example:
import "github.com/auth0/go-auth0/v2/management"
client, err := api.Client.Create(ctx, &management.Client{
Name: auth0.String("Existing Client"),
})
if err != nil {
if conflict, ok := err.(*management.ConflictError); ok {
fmt.Println("Resource already exists:", conflict.Body)
}
}
PreconditionFailedError (412)
type PreconditionFailedError struct {
*core.APIError
Body interface{}
}
The resource cannot be modified or deleted because it is in use. For example: “The Actions Module cannot be deleted because it is in use by one or more actions.”
ContentTooLargeError (413)
type ContentTooLargeError struct {
*core.APIError
Body interface{}
}
Payload content length greater than maximum allowed: 512000 bytes.
TooManyRequestsError (429)
type TooManyRequestsError struct {
*core.APIError
Body interface{}
}
Too many requests. Check the X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers.
Example:
import (
"time"
"github.com/auth0/go-auth0/v2/management"
)
client, err := api.Client.Read(ctx, clientID)
if err != nil {
if rateLimit, ok := err.(*management.TooManyRequestsError); ok {
// Implement exponential backoff or wait
fmt.Println("Rate limited:", rateLimit.Body)
time.Sleep(1 * time.Minute)
}
}
InternalServerError (500)
type InternalServerError struct {
*core.APIError
Body interface{}
}
Internal error on the Auth0 server.
ServiceUnavailableError (503)
type ServiceUnavailableError struct {
*core.APIError
Body interface{}
}
The query exceeded the timeout. Please try refining your search criteria. See Search Best Practices.
Error Handling Patterns
Type Assertion
Use type assertion to check for specific error types:
import "github.com/auth0/go-auth0/v2/management"
client, err := api.Client.Read(ctx, clientID)
if err != nil {
switch e := err.(type) {
case *management.NotFoundError:
fmt.Println("Client not found")
case *management.UnauthorizedError:
fmt.Println("Authentication failed")
case *management.ForbiddenError:
fmt.Println("Insufficient permissions")
case *management.TooManyRequestsError:
fmt.Println("Rate limited")
default:
fmt.Printf("Unknown error: %v\n", err)
}
}
Unwrapping Errors
All Management API errors implement the Unwrap() method, allowing you to access the underlying *core.APIError:
import (
"errors"
"github.com/auth0/go-auth0/v2/management"
"github.com/auth0/go-auth0/v2/management/core"
)
client, err := api.Client.Read(ctx, clientID)
if err != nil {
var apiErr *core.APIError
if errors.As(err, &apiErr) {
fmt.Printf("API Error: Status %d\n", apiErr.StatusCode)
}
}
Checking Status Codes
For Authentication API errors, check the status code directly:
import "github.com/auth0/go-auth0/v2/authentication"
token, err := authAPI.LoginWithPassword(ctx, request)
if err != nil {
if authErr, ok := err.(*authentication.Error); ok {
switch authErr.Status() {
case 401:
fmt.Println("Invalid credentials")
case 429:
fmt.Println("Too many login attempts")
case 500:
fmt.Println("Server error")
}
}
}
Checking Error Codes
For Authentication API errors, check the error code for specific conditions:
import "github.com/auth0/go-auth0/v2/authentication"
token, err := authAPI.LoginWithPassword(ctx, request)
if err != nil {
if authErr, ok := err.(*authentication.Error); ok {
switch authErr.Err {
case "mfa_required":
// Handle MFA flow
mfaToken := authErr.GetMFAToken()
// Proceed with MFA challenge
case "password_leaked":
// Force password reset
case "invalid_grant":
// Invalid credentials
}
}
}
Best Practices
-
Always check for errors: Never ignore errors returned by SDK methods
-
Use type assertions for specific handling: Use type switches or type assertions to handle different error types appropriately
-
Handle rate limiting gracefully: Implement exponential backoff when encountering
TooManyRequestsError
-
Check MFA requirements: For Authentication API calls, always check for MFA tokens when handling errors
-
Log error details: Log the full error body for debugging, but be careful not to log sensitive information
-
Implement retries carefully: Only retry idempotent operations and implement proper backoff strategies
-
Handle 404 errors appropriately: A
NotFoundError might be expected in some scenarios (e.g., checking if a resource exists)
Example: Comprehensive Error Handling
import (
"context"
"fmt"
"time"
"github.com/auth0/go-auth0/v2"
"github.com/auth0/go-auth0/v2/management"
)
func getClientWithRetry(api *management.Management, ctx context.Context, clientID string) (*management.Client, error) {
maxRetries := 3
for i := 0; i < maxRetries; i++ {
client, err := api.Client.Read(ctx, clientID)
if err == nil {
return client, nil
}
switch e := err.(type) {
case *management.NotFoundError:
// Client doesn't exist, no point retrying
return nil, fmt.Errorf("client not found: %s", clientID)
case *management.UnauthorizedError:
// Auth failed, no point retrying without new credentials
return nil, fmt.Errorf("authentication failed")
case *management.TooManyRequestsError:
// Rate limited, wait and retry
if i < maxRetries-1 {
waitTime := time.Duration(i+1) * time.Second
fmt.Printf("Rate limited, waiting %v before retry\n", waitTime)
time.Sleep(waitTime)
continue
}
return nil, fmt.Errorf("rate limited after %d retries", maxRetries)
case *management.InternalServerError:
// Server error, might be transient, retry
if i < maxRetries-1 {
fmt.Printf("Server error, retrying (attempt %d/%d)\n", i+1, maxRetries)
time.Sleep(time.Second)
continue
}
return nil, fmt.Errorf("server error after %d retries", maxRetries)
default:
// Unknown error
return nil, fmt.Errorf("unexpected error: %v", err)
}
}
return nil, fmt.Errorf("failed after %d retries", maxRetries)
}
See Also