I am no CORS expert, so maybe this is incorrect but here is what I am thinking w regards to preflight behavior.
Right now code:
https://github.com/Kong/kong/blob/master/kong/plugins/cors/handler.lua#L217
And Docs(which are slightly out of date on all the defaults and I PR'ed to update the default: https://github.com/Kong/docs.konghq.com/pull/1750 ):
https://docs.konghq.com/hub/kong-inc/cors/#parameters
State that the Access-Control-Allow-Methods by default will respond with a variety of default allowed methods during the preflight OPTIONS call.
I am finding in practice this is not the case and it returns empty value header. Code looks legit to me at a glance too, but something must not be set as expected.
I do find when I set the methods param to some value it then will respond to preflight appropriately. So just the defaulting behavior is currently broken, ex of working config with it set:
{
"created_at": 1580452083,
"config": {
"methods": [
"PATCH"
],
"exposed_headers": null,
"max_age": null,
"headers": null,
"origins": [
"*"
],
"credentials": true,
"preflight_continue": false
},
"id": "4a513f2e-ec76-47dc-a95a-813ae9f4ec81",
"service": null,
"enabled": true,
"name": "cors",
"protocols": [
"grpc",
"grpcs",
"http",
"https"
],
"run_on": "first",
"tags": null,
"route": {
"id": "feaa2ec2-6143-470c-9aa2-049abfccc95f"
},
"consumer": null
}
Set Method config CORS Plugin to Patch Preflight Response:
Connection →keep-alive
Access-Control-Allow-Origin →test.company.com
Access-Control-Allow-Credentials →true
Vary →Origin
Access-Control-Allow-Methods → PATCH
Content-Length →0
X-Response-Latency →14
This causes issues with a few client apps that do CORS and they expect proper Access-Control-Allow-Methods response. Not every CORS client pattern faces this kinda issue though:

methods config param empty, ex:{
"created_at": 1580452083,
"config": {
"methods": [],
"exposed_headers": null,
"max_age": null,
"headers": null,
"origins": [
"*"
],
"credentials": true,
"preflight_continue": false
},
"id": "4a513f2e-ec76-47dc-a95a-813ae9f4ec81",
"service": null,
"enabled": true,
"name": "cors",
"protocols": [
"grpc",
"grpcs",
"http",
"https"
],
"run_on": "first",
"tags": null,
"route": {
"id": "feaa2ec2-6143-470c-9aa2-049abfccc95f"
},
"consumer": null
}
Send a proxy OPTIONS call to it to kick off the preflight response, feel free to set Origins to something and Acess-Control-Request-Method if your feeling real fancy.
Witness the atrocity that is the empty Access-Control-Allow-Methods header blank:
No Set Method config CORS Plugin to Patch Preflight Response:
Connection →keep-alive
Access-Control-Allow-Origin →test.company.com
Access-Control-Allow-Credentials →true
Vary →Origin
Access-Control-Allow-Methods →
Content-Length →0
X-Response-Latency →12
@rainest Is this the same thing you've been experiencing? @bungle mentioned it looked similar.
No. We've encountered two customers where Access-Control-Allow-Origin isn't being sent downstream at all, both on Enterprise 0.34-1 (core 0.13-1) and 1.3.0.1. One of the customers mentioned this also, but it's not their core issue.
Looks like the real default should be "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS,TRACE,CONNECT", but I'm guessing conf.methods evaluates to true in your configuration because you've declared config.methods as an empty array. Is it possible to omit config.methods from your config entirely?
Re-testing and studying the case that is totally the issue, and actually my Konga UI is out of date and apparently has a fix for that problem here:
https://github.com/pantsel/konga/pull/446#issuecomment-582136189
I tested admin api directly with a PUT and the behavior was as desired with the defaults being set in the plugin by Kong.
So really it was just that empty list messes up getting the defaults. Not a Kong problem per say(although a point could be made in CORS the empty list should still use defaults because CORS with 0 allowed methods means pre-flight can never succeed, essentially an unusable proxy at that point).
Closing as resolved.
Most helpful comment
Looks like the real default should be
"GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS,TRACE,CONNECT", but I'm guessingconf.methodsevaluates to true in your configuration because you've declaredconfig.methodsas an empty array. Is it possible to omitconfig.methodsfrom your config entirely?