Customize Error Pages

If your callback URL is valid, when an authorization error occurs, the Authorization Server returns the appropriate error and state parameters to your callback URL. In cases where your callback URL is invalid, your application will display the default Auth0 generic error page.

Alternatively, you may get the generic error page for reasons other than invalid URLs, such as:

  • /authorize endpoint calls are missing parameters

  • password rest links in the Classic Universal Login experience are expired

  • login pages without a default login route specified are bookmarked and used

Parameters

If you choose to configure a custom error page, the Authorization Server will return parameters appended to the URL as a query string.

Parameter Description
client_id Identifier for the Auth0 application
connection Connection used at the time of error
lang Language set for use at the time of error
error Status code corresponding to the error
error_description Description of the error
tracking_id Identifier used by Auth0 support to find errors in internal logs
log_url Link to the error in your tenant logs

Parameters presented vary depending on the error type and are specific to the request. If, for example, the request which resulted in an error did not contain a client_id, no client ID will be returned by the error page.

Display a custom error page

If you choose to display a custom error page, you have two options:

  • Redirect users to a custom error page using either the dashboard or the Management API

  • Configure Auth0 to render a custom error page on your behalf via the Management API

Redirect users to a custom error page - Dashboard

Use the dashboard to configure Auth0 to redirect users to a custom error page:

  1. Navigate to Auth0 Dashboard > Tenant Settings.

  2. Locate the Error Pages section.

  3. Select the Redirect users to your own error page option.

  4. Enter the URL of the error page you would like your users to see, and select Save.

Redirect users to a custom error page - Management API

Use the Update Tenant Settings endpoint. Be sure to replace the MGMT_API_ACCESS_TOKEN placeholder value with your Management API Access Token, and update the url field in the JSON body to point to the location of the error page.


curl --request PATCH \
  --url 'https://YOUR_DOMAIN/api/v2/tenants/settings' \
  --header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
  --header 'content-type: application/json' \
  --data '{"error_page": {"html": "", "show_log_link":false, "url": "http://www.example.com"}}'
var client = new RestClient("https://YOUR_DOMAIN/api/v2/tenants/settings");
var request = new RestRequest(Method.PATCH);
request.AddHeader("authorization", "Bearer MGMT_API_ACCESS_TOKEN");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"error_page\": {\"html\": \"\", \"show_log_link\":false, \"url\": \"http://www.example.com\"}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io/ioutil"
)

func main() {

	url := "https://YOUR_DOMAIN/api/v2/tenants/settings"

	payload := strings.NewReader("{\"error_page\": {\"html\": \"\", \"show_log_link\":false, \"url\": \"http://www.example.com\"}}")

	req, _ := http.NewRequest("PATCH", url, payload)

	req.Header.Add("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
	req.Header.Add("content-type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.patch("https://YOUR_DOMAIN/api/v2/tenants/settings")
  .header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
  .header("content-type", "application/json")
  .body("{\"error_page\": {\"html\": \"\", \"show_log_link\":false, \"url\": \"http://www.example.com\"}}")
  .asString();
var axios = require("axios").default;

var options = {
  method: 'PATCH',
  url: 'https://YOUR_DOMAIN/api/v2/tenants/settings',
  headers: {
    authorization: 'Bearer MGMT_API_ACCESS_TOKEN',
    'content-type': 'application/json'
  },
  data: {error_page: {html: '', show_log_link: false, url: 'http://www.example.com'}}
};

axios.request(options).then(function (response) {
  console.log(response.data);
}).catch(function (error) {
  console.error(error);
});
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"authorization": @"Bearer MGMT_API_ACCESS_TOKEN",
                           @"content-type": @"application/json" };
NSDictionary *parameters = @{ @"error_page": @{ @"html": @"", @"show_log_link": @NO, @"url": @"http://www.example.com" } };

NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_DOMAIN/api/v2/tenants/settings"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"PATCH"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                if (error) {
                                                    NSLog(@"%@", error);
                                                } else {
                                                    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                    NSLog(@"%@", httpResponse);
                                                }
                                            }];
[dataTask resume];
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://YOUR_DOMAIN/api/v2/tenants/settings",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PATCH",
  CURLOPT_POSTFIELDS => "{\"error_page\": {\"html\": \"\", \"show_log_link\":false, \"url\": \"http://www.example.com\"}}",
  CURLOPT_HTTPHEADER => [
    "authorization: Bearer MGMT_API_ACCESS_TOKEN",
    "content-type: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("")

payload = "{\"error_page\": {\"html\": \"\", \"show_log_link\":false, \"url\": \"http://www.example.com\"}}"

headers = {
    'authorization': "Bearer MGMT_API_ACCESS_TOKEN",
    'content-type': "application/json"
    }

conn.request("PATCH", "/YOUR_DOMAIN/api/v2/tenants/settings", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://YOUR_DOMAIN/api/v2/tenants/settings")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Patch.new(url)
request["authorization"] = 'Bearer MGMT_API_ACCESS_TOKEN'
request["content-type"] = 'application/json'
request.body = "{\"error_page\": {\"html\": \"\", \"show_log_link\":false, \"url\": \"http://www.example.com\"}}"

response = http.request(request)
puts response.read_body
import Foundation

let headers = [
  "authorization": "Bearer MGMT_API_ACCESS_TOKEN",
  "content-type": "application/json"
]
let parameters = ["error_page": [
    "html": "",
    "show_log_link": false,
    "url": "http://www.example.com"
  ]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://YOUR_DOMAIN/api/v2/tenants/settings")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()

Value Description
MGMT_API_ACCESS_TOKEN Access Token for the Management API with the scope update:tenant_settings.
show_log_link Indicates whether to show a link to the error in your tenant logs. Valid values are true and false.
url Location of the custom error page to which you want to redirect.

Render a custom error page

Use the Update Tenant Settings endpoint. Be sure to replace the MGMT_API_ACCESS_TOKEN placeholder value with your Management API Access Token, and update the html field in the JSON body to a string containing the HTML of your page.

You can use Liquid syntax to include the following variables:

  • {client_id}

  • {connection}

  • {lang}

  • {error}

  • {error_description}

  • {tracking}


curl --request PATCH \
  --url https://login.auth0.com/api/v2/tenants/settings \
  --header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
  --header 'content-type: application/json' \
  --data '{"error_page": {"html": "<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'\''now'\'' | date: '\''%Y %h'\''}}.</h1>", "show_log_link": false, "url": ""}}'
var client = new RestClient("https://login.auth0.com/api/v2/tenants/settings");
var request = new RestRequest(Method.PATCH);
request.AddHeader("authorization", "Bearer MGMT_API_ACCESS_TOKEN");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"error_page\": {\"html\": \"<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.</h1>\", \"show_log_link\": false, \"url\": \"\"}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io/ioutil"
)

func main() {

	url := "https://login.auth0.com/api/v2/tenants/settings"

	payload := strings.NewReader("{\"error_page\": {\"html\": \"<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.</h1>\", \"show_log_link\": false, \"url\": \"\"}}")

	req, _ := http.NewRequest("PATCH", url, payload)

	req.Header.Add("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
	req.Header.Add("content-type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.patch("https://login.auth0.com/api/v2/tenants/settings")
  .header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
  .header("content-type", "application/json")
  .body("{\"error_page\": {\"html\": \"<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.</h1>\", \"show_log_link\": false, \"url\": \"\"}}")
  .asString();
var axios = require("axios").default;

var options = {
  method: 'PATCH',
  url: 'https://login.auth0.com/api/v2/tenants/settings',
  headers: {
    authorization: 'Bearer MGMT_API_ACCESS_TOKEN',
    'content-type': 'application/json'
  },
  data: {
    error_page: {
      html: '<h1>{{error | escape }} {{error_description | escape }} This error was generated {{\'now\' | date: \'%Y %h\'}}.</h1>',
      show_log_link: false,
      url: ''
    }
  }
};

axios.request(options).then(function (response) {
  console.log(response.data);
}).catch(function (error) {
  console.error(error);
});
#import <Foundation/Foundation.h>

NSDictionary *headers = @{ @"authorization": @"Bearer MGMT_API_ACCESS_TOKEN",
                           @"content-type": @"application/json" };
NSDictionary *parameters = @{ @"error_page": @{ @"html": @"<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.</h1>", @"show_log_link": @NO, @"url": @"" } };

NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://login.auth0.com/api/v2/tenants/settings"]
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10.0];
[request setHTTPMethod:@"PATCH"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                if (error) {
                                                    NSLog(@"%@", error);
                                                } else {
                                                    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                    NSLog(@"%@", httpResponse);
                                                }
                                            }];
[dataTask resume];
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://login.auth0.com/api/v2/tenants/settings",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PATCH",
  CURLOPT_POSTFIELDS => "{\"error_page\": {\"html\": \"<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.</h1>\", \"show_log_link\": false, \"url\": \"\"}}",
  CURLOPT_HTTPHEADER => [
    "authorization: Bearer MGMT_API_ACCESS_TOKEN",
    "content-type: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("login.auth0.com")

payload = "{\"error_page\": {\"html\": \"<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.</h1>\", \"show_log_link\": false, \"url\": \"\"}}"

headers = {
    'authorization': "Bearer MGMT_API_ACCESS_TOKEN",
    'content-type': "application/json"
    }

conn.request("PATCH", "/api/v2/tenants/settings", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://login.auth0.com/api/v2/tenants/settings")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Patch.new(url)
request["authorization"] = 'Bearer MGMT_API_ACCESS_TOKEN'
request["content-type"] = 'application/json'
request.body = "{\"error_page\": {\"html\": \"<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.</h1>\", \"show_log_link\": false, \"url\": \"\"}}"

response = http.request(request)
puts response.read_body
import Foundation

let headers = [
  "authorization": "Bearer MGMT_API_ACCESS_TOKEN",
  "content-type": "application/json"
]
let parameters = ["error_page": [
    "html": "<h1>{{error | escape }} {{error_description | escape }} This error was generated {{'now' | date: '%Y %h'}}.</h1>",
    "show_log_link": false,
    "url": ""
  ]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://login.auth0.com/api/v2/tenants/settings")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()

Value Description
MGMT_API_ACCESS_TOKEN Access Token for the Management API with the scope update:tenant_settings.
show_log_link Indicates whether to show a link to the error in your tenant logs. Valid values are true and false.
html HTML of the custom error page you want to render.

To prevent XSS vulnerabilities, sanitize your custom template using Liquid's escape and strip_html filters.

Learn more