Ktor 2.3.8 Help


If your server is supposed to handle cross-origin requests, you need to install and configure the CORS Ktor plugin. This plugin allows you to configure allowed hosts, HTTP methods, headers set by the client, and so on.

Add dependencies

To use CORS, you need to include the ktor-server-cors artifact in the build script:

implementation "io.ktor:ktor-server-cors:$ktor_version"
<dependency> <groupId>io.ktor</groupId> <artifactId>ktor-server-cors-jvm</artifactId> <version>${ktor_version}</version> </dependency>

Install CORS

To install the CORS plugin to the application, pass it to the install function in the specified module. The code snippets below show how to install CORS...

  • ... inside the embeddedServer function call.

  • ... inside the explicitly defined module, which is an extension function of the Application class.

import io.ktor.server.application.* import io.ktor.server.plugins.cors.* // ... fun main() { embeddedServer(Netty, port = 8080) { install(CORS) // ... }.start(wait = true) }
import io.ktor.server.application.* import io.ktor.server.plugins.cors.* // ... fun Application.module() { install(CORS) // ... }

The CORS plugin can also be installed to specific routes. This might be useful if you need different CORS configurations for different application resources.

Configure CORS

CORS-specific configuration settings are exposed by the CORSConfig class. Let's see how to configure these settings.


Suppose you have a server listening on the 8080 port, with the /customer route responding with JSON data. A code snippet below shows a sample request made using the Fetch API from the client working on another port to make this request cross-origin:

function saveCustomer() { fetch('', { headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, method: "POST", body: JSON.stringify({id: 3, firstName: "Jet", lastName: "Brains"}) }) .then(response => response.text()) .then(data => { console.log('Success:', data); alert(data); }) .catch((error) => { console.error('Error:', error); }); }

To allow such a request on the backend side, you need to configure the CORS plugin as follows:

install(CORS) { allowHost("") allowHeader(HttpHeaders.ContentType) }

You can find the full example here: cors.


To specify the allowed host that can make cross-origin requests, use the allowHost function. Apart from the hostname, you can specify a port number, a list of subdomains, or the supported HTTP schemes.

install(CORS) { allowHost("client-host") allowHost("client-host:8081") allowHost("client-host", subDomains = listOf("en", "de", "es")) allowHost("client-host", schemes = listOf("http", "https")) }

To allow cross-origin requests from any host, use the anyHost function.

install(CORS) { anyHost() }

HTTP methods

By default, the CORS plugin allows the GET, POST and HEAD HTTP methods. To add additional methods, use the allowMethod function.

install(CORS) { allowMethod(HttpMethod.Options) allowMethod(HttpMethod.Put) allowMethod(HttpMethod.Patch) allowMethod(HttpMethod.Delete) }

Allow headers

By default, the CORS plugin allows the following client headers managed by Access-Control-Allow-Headers:

  • Accept

  • Accept-Language

  • Content-Language

To allow additional headers, use the allowHeader function.

install(CORS) { allowHeader(HttpHeaders.ContentType) allowHeader(HttpHeaders.Authorization) }

To allow custom headers, use the allowHeaders or allowHeadersPrefixed functions. For instance, the code snippet below shows how to allow headers prefixed with custom-.

install(CORS) { allowHeadersPrefixed("custom-") }

Expose headers

The Access-Control-Expose-Headers header adds the specified headers to the allowlist that JavaScript in browsers can access. To configure such headers, use the exposeHeader function.

install(CORS) { // ... exposeHeader("X-My-Custom-Header") exposeHeader("X-Another-Custom-Header") }


By default, browsers don't send credential information (such as cookies or authentication information) with cross-origin requests. To allow passing this information, set the Access-Control-Allow-Credentials response header to true using the allowCredentials property.

install(CORS) { allowCredentials = true }


The CORS plugin also allows you to specify other CORS-related settings. For example, you can use maxAgeInSeconds to specify how long the response to the preflight request can be cached without sending another preflight request.

install(CORS) { maxAgeInSeconds = 3600 }

You can learn about other configuration options from CORSConfig.

Last modified: 12 January 2023